Merge "TrustManagerService.java: fix SynchronizeOnNonFinalField warning"
diff --git a/Android.bp b/Android.bp
index 5c059b5..33f3213 100644
--- a/Android.bp
+++ b/Android.bp
@@ -53,6 +53,7 @@
 subdirs = [
     "core/jni",
     "libs/*",
+    "media/*",
     "tools/*",
     "native/android",
     "native/graphics/jni",
diff --git a/Android.mk b/Android.mk
index 5529bfc..623b522 100644
--- a/Android.mk
+++ b/Android.mk
@@ -635,7 +635,6 @@
         frameworks/base/telephony/java/android/telephony/mbms/FileInfo.aidl \
         frameworks/base/telephony/java/android/telephony/mbms/FileServiceInfo.aidl \
         frameworks/base/telephony/java/android/telephony/mbms/ServiceInfo.aidl \
-	frameworks/base/telephony/java/android/telephony/mbms/StreamingService.aidl \
         frameworks/base/telephony/java/android/telephony/mbms/StreamingServiceInfo.aidl \
 	frameworks/base/telephony/java/android/telephony/ServiceState.aidl \
 	frameworks/base/telephony/java/android/telephony/SubscriptionInfo.aidl \
diff --git a/apct-tests/perftests/core/res/font/samplefont.ttf b/apct-tests/perftests/core/res/font/samplefont.ttf
new file mode 100644
index 0000000..b8302d4
--- /dev/null
+++ b/apct-tests/perftests/core/res/font/samplefont.ttf
Binary files differ
diff --git a/apct-tests/perftests/core/res/font/samplefont_source.ttx b/apct-tests/perftests/core/res/font/samplefont_source.ttx
new file mode 100644
index 0000000..40fa268
--- /dev/null
+++ b/apct-tests/perftests/core/res/font/samplefont_source.ttx
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
+<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.0">
+
+  <GlyphOrder>
+    <GlyphID id="0" name=".notdef"/>
+    <GlyphID id="1" name="a"/>
+  </GlyphOrder>
+
+  <head>
+    <tableVersion value="1.0"/>
+    <fontRevision value="1.0"/>
+    <checkSumAdjustment value="0x640cdb2f"/>
+    <magicNumber value="0x5f0f3cf5"/>
+    <flags value="00000000 00000011"/>
+    <unitsPerEm value="1000"/>
+    <created value="Fri Mar 17 07:26:00 2017"/>
+    <macStyle value="00000000 00000000"/>
+    <lowestRecPPEM value="7"/>
+    <fontDirectionHint value="2"/>
+    <glyphDataFormat value="0"/>
+  </head>
+
+  <hhea>
+    <tableVersion value="1.0"/>
+    <ascent value="1000"/>
+    <descent value="-200"/>
+    <lineGap value="0"/>
+    <caretSlopeRise value="1"/>
+    <caretSlopeRun value="0"/>
+    <caretOffset value="0"/>
+    <reserved0 value="0"/>
+    <reserved1 value="0"/>
+    <reserved2 value="0"/>
+    <reserved3 value="0"/>
+    <metricDataFormat value="0"/>
+  </hhea>
+
+  <maxp>
+    <tableVersion value="0x10000"/>
+    <maxZones value="0"/>
+    <maxTwilightPoints value="0"/>
+    <maxStorage value="0"/>
+    <maxFunctionDefs value="0"/>
+    <maxInstructionDefs value="0"/>
+    <maxStackElements value="0"/>
+    <maxSizeOfInstructions value="0"/>
+    <maxComponentElements value="0"/>
+  </maxp>
+
+  <OS_2>
+    <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
+         will be recalculated by the compiler -->
+    <version value="3"/>
+    <xAvgCharWidth value="594"/>
+    <usWeightClass value="400"/>
+    <usWidthClass value="5"/>
+    <fsType value="00000000 00001000"/>
+    <ySubscriptXSize value="650"/>
+    <ySubscriptYSize value="600"/>
+    <ySubscriptXOffset value="0"/>
+    <ySubscriptYOffset value="75"/>
+    <ySuperscriptXSize value="650"/>
+    <ySuperscriptYSize value="600"/>
+    <ySuperscriptXOffset value="0"/>
+    <ySuperscriptYOffset value="350"/>
+    <yStrikeoutSize value="50"/>
+    <yStrikeoutPosition value="300"/>
+    <sFamilyClass value="0"/>
+    <panose>
+      <bFamilyType value="0"/>
+      <bSerifStyle value="0"/>
+      <bWeight value="5"/>
+      <bProportion value="0"/>
+      <bContrast value="0"/>
+      <bStrokeVariation value="0"/>
+      <bArmStyle value="0"/>
+      <bLetterForm value="0"/>
+      <bMidline value="0"/>
+      <bXHeight value="0"/>
+    </panose>
+    <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
+    <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
+    <achVendID value="UKWN"/>
+    <fsSelection value="00000000 01000000"/>
+    <usFirstCharIndex value="32"/>
+    <usLastCharIndex value="122"/>
+    <sTypoAscender value="800"/>
+    <sTypoDescender value="-200"/>
+    <sTypoLineGap value="200"/>
+    <usWinAscent value="1000"/>
+    <usWinDescent value="200"/>
+    <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
+    <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
+    <sxHeight value="500"/>
+    <sCapHeight value="700"/>
+    <usDefaultChar value="0"/>
+    <usBreakChar value="32"/>
+    <usMaxContext value="0"/>
+  </OS_2>
+
+  <hmtx>
+    <mtx name=".notdef" width="500" lsb="93"/>
+    <mtx name="a" width="500" lsb="93"/>
+  </hmtx>
+
+  <cmap>
+    <tableVersion version="0"/>
+    <cmap_format_4 platformID="3" platEncID="10" language="0">
+      <map code="0x0061" name="a" />
+    </cmap_format_4>
+  </cmap>
+
+  <loca>
+    <!-- The 'loca' table will be calculated by the compiler -->
+  </loca>
+
+  <glyf>
+    <TTGlyph name=".notdef" xMin="0" yMin="0" xMax="0" yMax="0" />
+    <TTGlyph name="a" xMin="0" yMin="0" xMax="0" yMax="0" />
+  </glyf>
+
+  <name>
+    <namerecord nameID="1" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      Sample Font
+    </namerecord>
+    <namerecord nameID="2" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      Regular
+    </namerecord>
+    <namerecord nameID="4" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      Sample Font
+    </namerecord>
+    <namerecord nameID="6" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      SampleFont-Regular
+    </namerecord>
+    <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
+      Sample Font
+    </namerecord>
+    <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
+      Regular
+    </namerecord>
+    <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
+      Sample Font
+    </namerecord>
+    <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
+      SampleFont-Regular
+    </namerecord>
+  </name>
+
+  <post>
+    <formatType value="3.0"/>
+    <italicAngle value="0.0"/>
+    <underlinePosition value="-75"/>
+    <underlineThickness value="50"/>
+    <isFixedPitch value="0"/>
+    <minMemType42 value="0"/>
+    <maxMemType42 value="0"/>
+    <minMemType1 value="0"/>
+    <maxMemType1 value="0"/>
+  </post>
+
+</ttFont>
diff --git a/apct-tests/perftests/core/res/font/samplexmlfont.xml b/apct-tests/perftests/core/res/font/samplexmlfont.xml
new file mode 100644
index 0000000..b226446
--- /dev/null
+++ b/apct-tests/perftests/core/res/font/samplexmlfont.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 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
+-->
+<font-family xmlns:android="http://schemas.android.com/apk/res/android">
+    <font android:font="@font/samplefont" />
+</font-family>
diff --git a/apct-tests/perftests/core/res/layout/test_textview_font_family_file.xml b/apct-tests/perftests/core/res/layout/test_textview_font_family_file.xml
new file mode 100644
index 0000000..3689a64
--- /dev/null
+++ b/apct-tests/perftests/core/res/layout/test_textview_font_family_file.xml
@@ -0,0 +1,20 @@
+<!--
+ Copyright (C) 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
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+          android:layout_width="100dp"
+          android:layout_height="100dp"
+          android:text="@string/short_text"
+          android:fontFamily="@font/samplefont" />
diff --git a/apct-tests/perftests/core/res/layout/test_textview_font_family_string.xml b/apct-tests/perftests/core/res/layout/test_textview_font_family_string.xml
new file mode 100644
index 0000000..5f236f5
--- /dev/null
+++ b/apct-tests/perftests/core/res/layout/test_textview_font_family_string.xml
@@ -0,0 +1,20 @@
+<!--
+ Copyright (C) 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
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+          android:layout_width="100dp"
+          android:layout_height="100dp"
+          android:text="@string/short_text"
+          android:fontFamily="sans-serif" />
diff --git a/apct-tests/perftests/core/res/layout/test_textview_font_family_xml.xml b/apct-tests/perftests/core/res/layout/test_textview_font_family_xml.xml
new file mode 100644
index 0000000..0331fa5
--- /dev/null
+++ b/apct-tests/perftests/core/res/layout/test_textview_font_family_xml.xml
@@ -0,0 +1,20 @@
+<!--
+ Copyright (C) 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
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+          android:layout_width="100dp"
+          android:layout_height="100dp"
+          android:text="@string/short_text"
+          android:fontFamily="@font/samplexmlfont" />
diff --git a/apct-tests/perftests/core/res/values/strings.xml b/apct-tests/perftests/core/res/values/strings.xml
index 5d1f6f0..7ab325f 100644
--- a/apct-tests/perftests/core/res/values/strings.xml
+++ b/apct-tests/perftests/core/res/values/strings.xml
@@ -28,4 +28,5 @@
         text text text text text text text text text text text text text text text text
         text text text text text text text text text text text text text text text text
         text text text text text text text text text text text text </string>
+    <string name="short_text">text text</string>
 </resources>
diff --git a/apct-tests/perftests/core/src/android/os/SharedPreferencesTest.java b/apct-tests/perftests/core/src/android/os/SharedPreferencesTest.java
new file mode 100644
index 0000000..099134f
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/os/SharedPreferencesTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package android.os;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SharedPreferencesTest {
+    @Rule
+    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeCachedGetSharedPreferences() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        final Context context = InstrumentationRegistry.getTargetContext();
+        // Do the real work once as we're only interested in cache-hit performance
+        SharedPreferences prefs = context.getSharedPreferences("test", Context.MODE_PRIVATE);
+        while (state.keepRunning()) {
+            prefs = context.getSharedPreferences("test", Context.MODE_PRIVATE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/widget/TextViewFontFamilyLayoutPerfTest.java b/apct-tests/perftests/core/src/android/widget/TextViewFontFamilyLayoutPerfTest.java
new file mode 100644
index 0000000..4b6da6b
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/widget/TextViewFontFamilyLayoutPerfTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 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
+ */
+
+package android.widget;
+
+import android.content.Context;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.LayoutInflater;
+
+import com.android.perftests.core.R;
+
+import java.util.Collection;
+import java.util.Arrays;
+
+import org.junit.Test;
+import org.junit.Rule;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertTrue;
+
+@LargeTest
+@RunWith(Parameterized.class)
+public class TextViewFontFamilyLayoutPerfTest {
+    @Parameters(name = "{0}")
+    public static Collection layouts() {
+        return Arrays.asList(new Object[][] {
+                { "String fontFamily attribute", R.layout.test_textview_font_family_string},
+                { "File fontFamily attribute", R.layout.test_textview_font_family_file},
+                { "XML fontFamily attribute", R.layout.test_textview_font_family_xml},
+        });
+    }
+
+    private int mLayoutId;
+
+    public TextViewFontFamilyLayoutPerfTest(String key, int layoutId) {
+        mLayoutId = layoutId;
+    }
+
+    @Rule
+    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void testConstruction() throws Throwable {
+        final Context context = InstrumentationRegistry.getTargetContext();
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        final LayoutInflater inflator =
+                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+        while (state.keepRunning()) {
+            inflator.inflate(mLayoutId, null, false);
+        }
+    }
+}
diff --git a/api/removed.txt b/api/removed.txt
index f52b39a..9baafeb 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -254,18 +254,6 @@
     field public static final int BADGING_SD = 10; // 0xa
   }
 
-  public abstract class NetworkRecommendationProvider {
-    ctor public deprecated NetworkRecommendationProvider(android.os.Handler);
-    method public deprecated void onRequestRecommendation(android.net.RecommendationRequest, android.net.NetworkRecommendationProvider.ResultCallback);
-    field public static final deprecated java.lang.String EXTRA_RECOMMENDATION_RESULT = "android.net.extra.RECOMMENDATION_RESULT";
-    field public static final deprecated java.lang.String EXTRA_SEQUENCE = "android.net.extra.SEQUENCE";
-  }
-
-  public static deprecated class NetworkRecommendationProvider.ResultCallback {
-    ctor public NetworkRecommendationProvider.ResultCallback(android.os.IRemoteCallback, int);
-    method public void onResult(android.net.RecommendationResult);
-  }
-
   public abstract class PskKeyManager {
     ctor public PskKeyManager();
     field public static final int MAX_IDENTITY_HINT_LENGTH_BYTES = 128; // 0x80
@@ -273,37 +261,6 @@
     field public static final int MAX_KEY_LENGTH_BYTES = 256; // 0x100
   }
 
-  public final deprecated class RecommendationRequest implements android.os.Parcelable {
-    ctor protected RecommendationRequest(android.os.Parcel);
-    method public android.net.wifi.WifiConfiguration[] getConnectableConfigs();
-    method public android.net.wifi.WifiConfiguration getConnectedConfig();
-    method public android.net.wifi.WifiConfiguration getDefaultWifiConfig();
-    method public int getLastSelectedNetworkId();
-    method public long getLastSelectedNetworkTimestamp();
-    method public android.net.wifi.ScanResult[] getScanResults();
-    method public void setConnectableConfigs(android.net.wifi.WifiConfiguration[]);
-    method public void setConnectedConfig(android.net.wifi.WifiConfiguration);
-    field public static final android.os.Parcelable.Creator<android.net.RecommendationRequest> CREATOR;
-  }
-
-  public static final deprecated class RecommendationRequest.Builder {
-    ctor public RecommendationRequest.Builder();
-    method public android.net.RecommendationRequest build();
-    method public android.net.RecommendationRequest.Builder setConnectableConfigs(android.net.wifi.WifiConfiguration[]);
-    method public android.net.RecommendationRequest.Builder setConnectedWifiConfig(android.net.wifi.WifiConfiguration);
-    method public android.net.RecommendationRequest.Builder setDefaultWifiConfig(android.net.wifi.WifiConfiguration);
-    method public android.net.RecommendationRequest.Builder setLastSelectedNetwork(int, long);
-    method public android.net.RecommendationRequest.Builder setScanResults(android.net.wifi.ScanResult[]);
-  }
-
-  public final deprecated class RecommendationResult implements android.os.Parcelable {
-    method public static android.net.RecommendationResult createConnectRecommendation(android.net.wifi.WifiConfiguration);
-    method public static android.net.RecommendationResult createDoNotConnectRecommendation();
-    method public android.net.wifi.WifiConfiguration getWifiConfiguration();
-    method public boolean hasRecommendation();
-    field public static final android.os.Parcelable.Creator<android.net.RecommendationResult> CREATOR;
-  }
-
   public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory {
     method public static deprecated org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(int, android.net.SSLSessionCache);
   }
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 9f3970d..b1a29e7 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -252,18 +252,6 @@
     field public static final int BADGING_SD = 10; // 0xa
   }
 
-  public abstract class NetworkRecommendationProvider {
-    ctor public deprecated NetworkRecommendationProvider(android.os.Handler);
-    method public deprecated void onRequestRecommendation(android.net.RecommendationRequest, android.net.NetworkRecommendationProvider.ResultCallback);
-    field public static final deprecated java.lang.String EXTRA_RECOMMENDATION_RESULT = "android.net.extra.RECOMMENDATION_RESULT";
-    field public static final deprecated java.lang.String EXTRA_SEQUENCE = "android.net.extra.SEQUENCE";
-  }
-
-  public static deprecated class NetworkRecommendationProvider.ResultCallback {
-    ctor public NetworkRecommendationProvider.ResultCallback(android.os.IRemoteCallback, int);
-    method public void onResult(android.net.RecommendationResult);
-  }
-
   public abstract class PskKeyManager {
     ctor public PskKeyManager();
     field public static final int MAX_IDENTITY_HINT_LENGTH_BYTES = 128; // 0x80
@@ -271,37 +259,6 @@
     field public static final int MAX_KEY_LENGTH_BYTES = 256; // 0x100
   }
 
-  public final deprecated class RecommendationRequest implements android.os.Parcelable {
-    ctor protected RecommendationRequest(android.os.Parcel);
-    method public android.net.wifi.WifiConfiguration[] getConnectableConfigs();
-    method public android.net.wifi.WifiConfiguration getConnectedConfig();
-    method public android.net.wifi.WifiConfiguration getDefaultWifiConfig();
-    method public int getLastSelectedNetworkId();
-    method public long getLastSelectedNetworkTimestamp();
-    method public android.net.wifi.ScanResult[] getScanResults();
-    method public void setConnectableConfigs(android.net.wifi.WifiConfiguration[]);
-    method public void setConnectedConfig(android.net.wifi.WifiConfiguration);
-    field public static final android.os.Parcelable.Creator<android.net.RecommendationRequest> CREATOR;
-  }
-
-  public static final deprecated class RecommendationRequest.Builder {
-    ctor public RecommendationRequest.Builder();
-    method public android.net.RecommendationRequest build();
-    method public android.net.RecommendationRequest.Builder setConnectableConfigs(android.net.wifi.WifiConfiguration[]);
-    method public android.net.RecommendationRequest.Builder setConnectedWifiConfig(android.net.wifi.WifiConfiguration);
-    method public android.net.RecommendationRequest.Builder setDefaultWifiConfig(android.net.wifi.WifiConfiguration);
-    method public android.net.RecommendationRequest.Builder setLastSelectedNetwork(int, long);
-    method public android.net.RecommendationRequest.Builder setScanResults(android.net.wifi.ScanResult[]);
-  }
-
-  public final deprecated class RecommendationResult implements android.os.Parcelable {
-    method public static android.net.RecommendationResult createConnectRecommendation(android.net.wifi.WifiConfiguration);
-    method public static android.net.RecommendationResult createDoNotConnectRecommendation();
-    method public android.net.wifi.WifiConfiguration getWifiConfiguration();
-    method public boolean hasRecommendation();
-    field public static final android.os.Parcelable.Creator<android.net.RecommendationResult> CREATOR;
-  }
-
   public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory {
     method public static deprecated org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(int, android.net.SSLSessionCache);
   }
diff --git a/api/test-removed.txt b/api/test-removed.txt
index f52b39a..9baafeb 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -254,18 +254,6 @@
     field public static final int BADGING_SD = 10; // 0xa
   }
 
-  public abstract class NetworkRecommendationProvider {
-    ctor public deprecated NetworkRecommendationProvider(android.os.Handler);
-    method public deprecated void onRequestRecommendation(android.net.RecommendationRequest, android.net.NetworkRecommendationProvider.ResultCallback);
-    field public static final deprecated java.lang.String EXTRA_RECOMMENDATION_RESULT = "android.net.extra.RECOMMENDATION_RESULT";
-    field public static final deprecated java.lang.String EXTRA_SEQUENCE = "android.net.extra.SEQUENCE";
-  }
-
-  public static deprecated class NetworkRecommendationProvider.ResultCallback {
-    ctor public NetworkRecommendationProvider.ResultCallback(android.os.IRemoteCallback, int);
-    method public void onResult(android.net.RecommendationResult);
-  }
-
   public abstract class PskKeyManager {
     ctor public PskKeyManager();
     field public static final int MAX_IDENTITY_HINT_LENGTH_BYTES = 128; // 0x80
@@ -273,37 +261,6 @@
     field public static final int MAX_KEY_LENGTH_BYTES = 256; // 0x100
   }
 
-  public final deprecated class RecommendationRequest implements android.os.Parcelable {
-    ctor protected RecommendationRequest(android.os.Parcel);
-    method public android.net.wifi.WifiConfiguration[] getConnectableConfigs();
-    method public android.net.wifi.WifiConfiguration getConnectedConfig();
-    method public android.net.wifi.WifiConfiguration getDefaultWifiConfig();
-    method public int getLastSelectedNetworkId();
-    method public long getLastSelectedNetworkTimestamp();
-    method public android.net.wifi.ScanResult[] getScanResults();
-    method public void setConnectableConfigs(android.net.wifi.WifiConfiguration[]);
-    method public void setConnectedConfig(android.net.wifi.WifiConfiguration);
-    field public static final android.os.Parcelable.Creator<android.net.RecommendationRequest> CREATOR;
-  }
-
-  public static final deprecated class RecommendationRequest.Builder {
-    ctor public RecommendationRequest.Builder();
-    method public android.net.RecommendationRequest build();
-    method public android.net.RecommendationRequest.Builder setConnectableConfigs(android.net.wifi.WifiConfiguration[]);
-    method public android.net.RecommendationRequest.Builder setConnectedWifiConfig(android.net.wifi.WifiConfiguration);
-    method public android.net.RecommendationRequest.Builder setDefaultWifiConfig(android.net.wifi.WifiConfiguration);
-    method public android.net.RecommendationRequest.Builder setLastSelectedNetwork(int, long);
-    method public android.net.RecommendationRequest.Builder setScanResults(android.net.wifi.ScanResult[]);
-  }
-
-  public final deprecated class RecommendationResult implements android.os.Parcelable {
-    method public static android.net.RecommendationResult createConnectRecommendation(android.net.wifi.WifiConfiguration);
-    method public static android.net.RecommendationResult createDoNotConnectRecommendation();
-    method public android.net.wifi.WifiConfiguration getWifiConfiguration();
-    method public boolean hasRecommendation();
-    field public static final android.os.Parcelable.Creator<android.net.RecommendationResult> CREATOR;
-  }
-
   public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory {
     method public static deprecated org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(int, android.net.SSLSessionCache);
   }
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 18234f0..d8c8cb9 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -1346,6 +1346,8 @@
         for (int n = 0; n < nodeCount; n++) {
             final Node node = mNodes.get(n);
             Node nodeClone = node.clone();
+            // Remove the old internal listener from the cloned child
+            nodeClone.mAnimation.removeListener(mDummyListener);
             clonesMap.put(node, nodeClone);
             anim.mNodes.add(nodeClone);
             anim.mNodeMap.put(nodeClone.mAnimation, nodeClone);
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 3eec596..53608fb 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -38,6 +38,7 @@
 import android.util.Pair;
 import android.util.Slog;
 import android.view.AppTransitionAnimationSpec;
+import android.view.IAppTransitionAnimationSpecsFuture;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
@@ -213,6 +214,7 @@
 
     private static final String KEY_INSTANT_APP_VERIFICATION_BUNDLE
             = "android:instantapps.installerbundle";
+    private static final String KEY_SPECS_FUTURE = "android:activity.specsFuture";
 
     /** @hide */
     public static final int ANIM_NONE = 0;
@@ -268,6 +270,7 @@
     private AppTransitionAnimationSpec mAnimSpecs[];
     private int mRotationAnimationHint = -1;
     private Bundle mAppVerificationBundle;
+    private IAppTransitionAnimationSpecsFuture mSpecsFuture;
 
     /**
      * Create an ActivityOptions specifying a custom animation to run when
@@ -492,35 +495,12 @@
      * is not executed, the callback will happen immediately.
      * @return Returns a new ActivityOptions object that you can use to
      * supply these options as the options Bundle when starting an activity.
-     * @hide
      */
-    public static ActivityOptions makeThumbnailScaleUpAnimation(View source,
+    private static ActivityOptions makeThumbnailScaleUpAnimation(View source,
             Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
         return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, true);
     }
 
-    /**
-     * Create an ActivityOptions specifying an animation where an activity window
-     * is scaled from a given position to a thumbnail at a specified location.
-     *
-     * @param source The View that this thumbnail is animating to.  This
-     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
-     * @param thumbnail The bitmap that will be shown as the final thumbnail
-     * of the animation.
-     * @param startX The x end location of the bitmap, relative to <var>source</var>.
-     * @param startY The y end location of the bitmap, relative to <var>source</var>.
-     * @param listener Optional OnAnimationStartedListener to find out when the
-     * requested animation has started running.  If for some reason the animation
-     * is not executed, the callback will happen immediately.
-     * @return Returns a new ActivityOptions object that you can use to
-     * supply these options as the options Bundle when starting an activity.
-     * @hide
-     */
-    public static ActivityOptions makeThumbnailScaleDownAnimation(View source,
-            Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
-        return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, false);
-    }
-
     private static ActivityOptions makeThumbnailAnimation(View source,
             Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener,
             boolean scaleUp) {
@@ -537,29 +517,21 @@
     }
 
     /**
-     * Create an ActivityOptions specifying an animation where the new activity
-     * window and a thumbnail is aspect-scaled to a new location.
-     *
-     * @param source The View that this thumbnail is animating from.  This
-     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
-     * @param thumbnail The bitmap that will be shown as the initial thumbnail
-     * of the animation.
-     * @param startX The x starting location of the bitmap, relative to <var>source</var>.
-     * @param startY The y starting location of the bitmap, relative to <var>source</var>.
-     * @param handler If <var>listener</var> is non-null this must be a valid
-     * Handler on which to dispatch the callback; otherwise it should be null.
-     * @param listener Optional OnAnimationStartedListener to find out when the
-     * requested animation has started running.  If for some reason the animation
-     * is not executed, the callback will happen immediately.
-     * @return Returns a new ActivityOptions object that you can use to
-     * supply these options as the options Bundle when starting an activity.
+     * Create an ActivityOptions specifying an animation where a list of activity windows and
+     * thumbnails are aspect scaled to/from a new location.
      * @hide
      */
-    public static ActivityOptions makeThumbnailAspectScaleUpAnimation(View source,
-            Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight,
-            Handler handler, OnAnimationStartedListener listener) {
-        return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY,
-                targetWidth, targetHeight, handler, listener, true);
+    public static ActivityOptions makeMultiThumbFutureAspectScaleAnimation(Context context,
+            Handler handler, IAppTransitionAnimationSpecsFuture specsFuture,
+            OnAnimationStartedListener listener, boolean scaleUp) {
+        ActivityOptions opts = new ActivityOptions();
+        opts.mPackageName = context.getPackageName();
+        opts.mAnimationType = scaleUp
+                ? ANIM_THUMBNAIL_ASPECT_SCALE_UP
+                : ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
+        opts.mSpecsFuture = specsFuture;
+        opts.setOnAnimationStartedListener(handler, listener);
+        return opts;
     }
 
     /**
@@ -891,6 +863,10 @@
         }
         mRotationAnimationHint = opts.getInt(KEY_ROTATION_ANIMATION_HINT);
         mAppVerificationBundle = opts.getBundle(KEY_INSTANT_APP_VERIFICATION_BUNDLE);
+        if (opts.containsKey(KEY_SPECS_FUTURE)) {
+            mSpecsFuture = IAppTransitionAnimationSpecsFuture.Stub.asInterface(opts.getBinder(
+                    KEY_SPECS_FUTURE));
+        }
     }
 
     /**
@@ -1029,6 +1005,11 @@
     public AppTransitionAnimationSpec[] getAnimSpecs() { return mAnimSpecs; }
 
     /** @hide */
+    public IAppTransitionAnimationSpecsFuture getSpecsFuture() {
+        return mSpecsFuture;
+    }
+
+    /** @hide */
     public static ActivityOptions fromBundle(Bundle bOptions) {
         return bOptions != null ? new ActivityOptions(bOptions) : null;
     }
@@ -1205,6 +1186,7 @@
         }
         mAnimSpecs = otherOptions.mAnimSpecs;
         mAnimationFinishedListener = otherOptions.mAnimationFinishedListener;
+        mSpecsFuture = otherOptions.mSpecsFuture;
     }
 
     /**
@@ -1279,6 +1261,9 @@
         if (mAnimationFinishedListener != null) {
             b.putBinder(KEY_ANIMATION_FINISHED_LISTENER, mAnimationFinishedListener.asBinder());
         }
+        if (mSpecsFuture != null) {
+            b.putBinder(KEY_SPECS_FUTURE, mSpecsFuture.asBinder());
+        }
         b.putInt(KEY_ROTATION_ANIMATION_HINT, mRotationAnimationHint);
         if (mAppVerificationBundle != null) {
             b.putBundle(KEY_INSTANT_APP_VERIFICATION_BUNDLE, mAppVerificationBundle);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 928ef7e..ed706fc 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -5477,15 +5477,6 @@
         android.ddm.DdmHandleAppName.setAppName(data.processName,
                                                 UserHandle.myUserId());
 
-        if (data.persistent) {
-            // Persistent processes on low-memory devices do not get to
-            // use hardware accelerated drawing, since this can add too much
-            // overhead to the process.
-            if (!ActivityManager.isHighEndGfx()) {
-                ThreadedRenderer.disable(false);
-            }
-        }
-
         if (mProfiler.profileFd != null) {
             mProfiler.startProfiling();
         }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 1dcc3e2..bfc5891 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -63,7 +63,6 @@
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
 import android.system.ErrnoException;
@@ -373,21 +372,21 @@
 
     @Override
     public SharedPreferences getSharedPreferences(File file, int mode) {
-        checkMode(mode);
-        if (getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.O) {
-            if (isCredentialProtectedStorage()
-                    && !getSystemService(StorageManager.class).isUserKeyUnlocked(
-                            UserHandle.myUserId())
-                    && !isBuggy()) {
-                throw new IllegalStateException("SharedPreferences in credential encrypted "
-                        + "storage are not available until after user is unlocked");
-            }
-        }
         SharedPreferencesImpl sp;
         synchronized (ContextImpl.class) {
             final ArrayMap<File, SharedPreferencesImpl> cache = getSharedPreferencesCacheLocked();
             sp = cache.get(file);
             if (sp == null) {
+                checkMode(mode);
+                if (getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.O) {
+                    if (isCredentialProtectedStorage()
+                            && !getSystemService(StorageManager.class).isUserKeyUnlocked(
+                            UserHandle.myUserId())
+                            && !isBuggy()) {
+                        throw new IllegalStateException("SharedPreferences in credential encrypted "
+                                + "storage are not available until after user is unlocked");
+                    }
+                }
                 sp = new SharedPreferencesImpl(file, mode);
                 cache.put(file, sp);
                 return sp;
@@ -845,8 +844,9 @@
         // Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is
         // generally not allowed, except if the caller specifies the task id the activity should
         // be launched in.
-        if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0
-                && options != null && ActivityOptions.fromBundle(options).getLaunchTaskId() == -1) {
+        if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
+                && (options == null
+                || ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) {
             throw new AndroidRuntimeException(
                     "Calling startActivity() from outside of an Activity "
                     + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 1b2543c..95d55dc 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -2303,11 +2303,15 @@
      */
     private void completeExecute(BackStackRecord record, boolean isPop, boolean runTransitions,
             boolean moveToState) {
+        if (isPop) {
+            record.executePopOps(moveToState);
+        } else {
+            record.executeOps();
+        }
         ArrayList<BackStackRecord> records = new ArrayList<>(1);
         ArrayList<Boolean> isRecordPop = new ArrayList<>(1);
         records.add(record);
         isRecordPop.add(isPop);
-        executeOps(records, isRecordPop, 0, 1);
         if (runTransitions) {
             FragmentTransition.startTransitions(this, records, isRecordPop, 0, 1, true);
         }
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index 4994fbb..b5b1017 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -30,7 +30,7 @@
     void onTaskStackChanged();
 
     /** Called whenever an Activity is moved to the pinned stack from another stack. */
-    void onActivityPinned(String packageName);
+    void onActivityPinned(String packageName, int taskId);
 
     /** Called whenever an Activity is moved from the pinned stack to another stack. */
     void onActivityUnpinned();
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 8a15b1f..3ed174b 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1112,6 +1112,16 @@
     @SystemApi
     public static final String EXTRA_SUBSTITUTE_APP_NAME = "android.substName";
 
+    /**
+     * This is set on the notification shown by the activity manager about all apps
+     * running in the background.  It indicates that the notification should be shown
+     * only if any of the given apps do not already have a {@link #FLAG_FOREGROUND_SERVICE}
+     * notification currently visible to the user.  This is a string array of all
+     * package names of the apps.
+     * @hide
+     */
+    public static final String EXTRA_FOREGROUND_APPS = "android.foregroundApps";
+
     private Icon mSmallIcon;
     private Icon mLargeIcon;
 
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 2df011f..a52ca0a 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -31,7 +31,7 @@
     }
 
     @Override
-    public void onActivityPinned(String packageName) throws RemoteException {
+    public void onActivityPinned(String packageName, int taskId) throws RemoteException {
     }
 
     @Override
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index ce8b05a..0d7a941 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -15,10 +15,13 @@
  */
 package android.app.usage;
 
+import android.annotation.IntDef;
 import android.content.res.Configuration;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
 import java.util.List;
 
@@ -28,6 +31,12 @@
  */
 public final class UsageEvents implements Parcelable {
 
+    /** @hide */
+    public static final String INSTANT_APP_PACKAGE_NAME = "android.instant_app";
+
+    /** @hide */
+    public static final String INSTANT_APP_CLASS_NAME = "android.instant_class";
+
     /**
      * An event representing a state change for a component.
      */
@@ -91,6 +100,17 @@
          */
         public static final int CHOOSER_ACTION = 9;
 
+        /** @hide */
+        public static final int FLAG_IS_PACKAGE_INSTANT_APP = 1 << 0;
+
+        /** @hide */
+        @IntDef(flag = true,
+                value = {
+                        FLAG_IS_PACKAGE_INSTANT_APP,
+                })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface EventFlags {}
+
         /**
          * {@hide}
          */
@@ -145,6 +165,27 @@
          */
         public String[] mContentAnnotations;
 
+        /** @hide */
+        @EventFlags
+        public int mFlags;
+
+        public Event() {
+        }
+
+        /** @hide */
+        public Event(Event orig) {
+            mPackage = orig.mPackage;
+            mClass = orig.mClass;
+            mTimeStamp = orig.mTimeStamp;
+            mEventType = orig.mEventType;
+            mConfiguration = orig.mConfiguration;
+            mShortcutId = orig.mShortcutId;
+            mAction = orig.mAction;
+            mContentType = orig.mContentType;
+            mContentAnnotations = orig.mContentAnnotations;
+            mFlags = orig.mFlags;
+        }
+
         /**
          * The package name of the source of this event.
          */
@@ -196,6 +237,20 @@
         public String getShortcutId() {
             return mShortcutId;
         }
+
+        /** @hide */
+        public Event getObfuscatedIfInstantApp() {
+            if ((mFlags & FLAG_IS_PACKAGE_INSTANT_APP) == 0) {
+                return this;
+            }
+            final Event ret = new Event(this);
+            ret.mPackage = INSTANT_APP_PACKAGE_NAME;
+            ret.mClass = INSTANT_APP_CLASS_NAME;
+
+            // Note there are other string fields too, but they're for app shortcuts and choosers,
+            // which instant apps can't use anyway, so there's no need to hide them.
+            return ret;
+        }
     }
 
     // Only used when creating the resulting events. Not used for reading/unparceling.
diff --git a/core/java/android/app/usage/UsageStats.java b/core/java/android/app/usage/UsageStats.java
index 0874095..7eef85c 100644
--- a/core/java/android/app/usage/UsageStats.java
+++ b/core/java/android/app/usage/UsageStats.java
@@ -85,6 +85,17 @@
         mChooserCounts = stats.mChooserCounts;
     }
 
+    /**
+     * {@hide}
+     */
+    public UsageStats getObfuscatedForInstantApp() {
+        final UsageStats ret = new UsageStats(this);
+
+        ret.mPackageName = UsageEvents.INSTANT_APP_PACKAGE_NAME;
+
+        return ret;
+    }
+
     public String getPackageName() {
         return mPackageName;
     }
diff --git a/core/java/android/app/usage/UsageStatsManagerInternal.java b/core/java/android/app/usage/UsageStatsManagerInternal.java
index 08595dd..dbaace2 100644
--- a/core/java/android/app/usage/UsageStatsManagerInternal.java
+++ b/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -127,7 +127,12 @@
 
     public abstract void applyRestoredPayload(int user, String key, byte[] payload);
 
-    /* Cache Quota Service API */
+    /**
+     * Return usage stats.
+     *
+     * @param obfuscateInstantApps whether instant app package names need to be obfuscated in the
+     *     result.
+     */
     public abstract List<UsageStats> queryUsageStatsForUser(
-            int userId, int interval, long beginTime, long endTime);
+            int userId, int interval, long beginTime, long endTime, boolean obfuscateInstantApps);
 }
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 5fabbb6..a3d6e9f 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -16,7 +16,6 @@
 
 package android.bluetooth;
 
-import android.content.Context;
 import android.os.Handler;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
@@ -927,6 +926,31 @@
     }
 
     /**
+     * Discovers a service by UUID. This is exposed only for passing PTS tests.
+     * It should never be used by real applications. The service is not searched
+     * for characteristics and descriptors, or returned in any callback.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+     *
+     * @return true, if the remote service discovery has been started
+     * @hide
+     */
+    public boolean discoverServiceByUuid(UUID uuid) {
+        if (DBG) Log.d(TAG, "discoverServiceByUuid() - device: " + mDevice.getAddress());
+        if (mService == null || mClientIf == 0) return false;
+
+        mServices.clear();
+
+        try {
+            mService.discoverServiceByUuid(mClientIf, mDevice.getAddress(), new ParcelUuid(uuid));
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+            return false;
+        }
+        return true;
+    }
+
+    /**
      * Returns a list of GATT services offered by the remote device.
      *
      * <p>This function requires that service discovery has been completed
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index dc5c7b6..167f5e9 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -80,6 +80,7 @@
     void clientReadPhy(in int clientIf, in String address);
     void refreshDevice(in int clientIf, in String address);
     void discoverServices(in int clientIf, in String address);
+    void discoverServiceByUuid(in int clientIf, in String address, in ParcelUuid uuid);
     void readCharacteristic(in int clientIf, in String address, in int handle, in int authReq);
     void readUsingCharacteristicUuid(in int clientIf, in String address, in ParcelUuid uuid,
                            in int startHandle, in int endHandle, in int authReq);
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 426f3cf..87e6a84 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -341,4 +341,7 @@
      * Return the taget SDK version for the app with the given UID.
      */
     public abstract int getUidTargetSdkVersion(int uid);
+
+    /** Whether the binder caller can access instant apps. */
+    public abstract boolean canAccessInstantApps(int callingUid);
 }
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index bdfef83..b3adf82 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -772,6 +772,10 @@
         }
 
         final String file = value.string.toString();
+        if (!file.startsWith("res/")) {
+            return null;
+        }
+
         Typeface cached = Typeface.findFromCache(mAssets, file);
         if (cached != null) {
             return cached;
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 8e57e85..b00e65a 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -100,8 +100,8 @@
     public static final int FINGERPRINT_ERROR_CANCELED = 5;
 
     /**
-     * The {@link FingerprintManager#remove(Fingerprint, RemovalCallback)} call failed. Typically
-     * this will happen when the provided fingerprint id was incorrect.
+     * The {@link FingerprintManager#remove} call failed. Typically this will happen when the
+     * provided fingerprint id was incorrect.
      *
      * @hide
      */
@@ -398,10 +398,10 @@
     };
 
     /**
-     * Callback structure provided to {@link FingerprintManager#remove(int). Users of
-     * {@link #FingerprintManager()} may optionally provide an implementation of this to
-     * {@link FingerprintManager#remove(int, int, RemovalCallback)} for listening to
-     * fingerprint template removal events.
+     * Callback structure provided to {@link #remove}. Users of {@link FingerprintManager} may
+     * optionally provide an implementation of this to
+     * {@link #remove(Fingerprint, int, RemovalCallback)} for listening to fingerprint template
+     * removal events.
      *
      * @hide
      */
@@ -416,9 +416,13 @@
 
         /**
          * Called when a given fingerprint is successfully removed.
-         * @param fingerprint the fingerprint template that was removed.
+         * @param fp The fingerprint template that was removed.
+         * @param remaining The number of fingerprints yet to be removed in this operation. If
+         *         {@link #remove} is called on one fingerprint, this should be 0. If
+         *         {@link #remove} is called on a group, this should be the number of remaining
+         *         fingerprints in the group, and 0 after the last fingerprint is removed.
          */
-        public void onRemovalSucceeded(Fingerprint fingerprint) { }
+        public void onRemovalSucceeded(Fingerprint fp, int remaining) { }
     };
 
     /**
@@ -878,8 +882,7 @@
                             msg.arg2 /* vendorCode */);
                     break;
                 case MSG_REMOVED:
-                    sendRemovedResult((Long) msg.obj /* deviceId */, msg.arg1 /* fingerId */,
-                            msg.arg2 /* groupId */);
+                    sendRemovedResult((Fingerprint) msg.obj, msg.arg1 /* remaining */);
                     break;
                 case MSG_ENUMERATED:
                     sendEnumeratedResult((Long) msg.obj /* deviceId */, msg.arg1 /* fingerId */,
@@ -888,21 +891,29 @@
             }
         }
 
-        private void sendRemovedResult(long deviceId, int fingerId, int groupId) {
-            if (mRemovalCallback != null) {
-                int reqFingerId = mRemovalFingerprint.getFingerId();
-                int reqGroupId = mRemovalFingerprint.getGroupId();
-                if (reqFingerId != 0 && fingerId != 0  &&  fingerId != reqFingerId) {
-                    Log.w(TAG, "Finger id didn't match: " + fingerId + " != " + reqFingerId);
-                    return;
-                }
-                if (groupId != reqGroupId) {
-                    Log.w(TAG, "Group id didn't match: " + groupId + " != " + reqGroupId);
-                    return;
-                }
-                mRemovalCallback.onRemovalSucceeded(new Fingerprint(null, groupId, fingerId,
-                        deviceId));
+        private void sendRemovedResult(Fingerprint fingerprint, int remaining) {
+            if (mRemovalCallback == null) {
+                return;
             }
+            if (fingerprint == null) {
+                Log.e(TAG, "Received MSG_REMOVED, but fingerprint is null");
+                return;
+            }
+
+            int fingerId = fingerprint.getFingerId();
+            int reqFingerId = mRemovalFingerprint.getFingerId();
+            if (reqFingerId != 0 && fingerId != 0 && fingerId != reqFingerId) {
+                Log.w(TAG, "Finger id didn't match: " + fingerId + " != " + reqFingerId);
+                return;
+            }
+            int groupId = fingerprint.getGroupId();
+            int reqGroupId = mRemovalFingerprint.getGroupId();
+            if (groupId != reqGroupId) {
+                Log.w(TAG, "Group id didn't match: " + groupId + " != " + reqGroupId);
+                return;
+            }
+
+            mRemovalCallback.onRemovalSucceeded(fingerprint, remaining);
         }
 
         private void sendEnumeratedResult(long deviceId, int fingerId, int groupId) {
@@ -1100,8 +1111,8 @@
 
         @Override // binder call
         public void onRemoved(long deviceId, int fingerId, int groupId, int remaining) {
-            // TODO: propagate remaining
-            mHandler.obtainMessage(MSG_REMOVED, fingerId, groupId, deviceId).sendToTarget();
+            mHandler.obtainMessage(MSG_REMOVED, remaining, 0,
+                    new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
         }
 
         @Override // binder call
diff --git a/core/java/android/hardware/radio/ITuner.aidl b/core/java/android/hardware/radio/ITuner.aidl
index 4e6a1e7..1fc71e0 100644
--- a/core/java/android/hardware/radio/ITuner.aidl
+++ b/core/java/android/hardware/radio/ITuner.aidl
@@ -58,4 +58,32 @@
     void cancel();
 
     RadioManager.ProgramInfo getProgramInformation();
+
+    /**
+     * @returns {@code true} if the scan was properly scheduled,
+     *          {@code false} if the scan feature is unavailable
+     */
+    boolean startBackgroundScan();
+
+    /**
+     * @returns the list, or null if scan is in progress
+     * @throws IllegalArgumentException if invalid arguments are passed
+     * @throws IllegalStateException if the scan has not been started, client may
+     *         call startBackgroundScan to fix this.
+     */
+    List<RadioManager.ProgramInfo> getProgramList(String filter);
+
+    /**
+     * @throws IllegalStateException if the switch is not supported at current
+     *         configuration.
+     */
+    boolean isAnalogForced();
+
+    /**
+     * @throws IllegalStateException if the switch is not supported at current
+     *         configuration.
+     */
+    void setAnalogForced(boolean isForced);
+
+    boolean isAntennaConnected();
 }
diff --git a/core/java/android/hardware/radio/TunerAdapter.java b/core/java/android/hardware/radio/TunerAdapter.java
index bffca61..a457494 100644
--- a/core/java/android/hardware/radio/TunerAdapter.java
+++ b/core/java/android/hardware/radio/TunerAdapter.java
@@ -182,32 +182,47 @@
 
     @Override
     public boolean startBackgroundScan() {
-        // TODO(b/36863239): forward to mTuner
-        throw new RuntimeException("Not implemented");
+        try {
+            return mTuner.startBackgroundScan();
+        } catch (RemoteException e) {
+            throw new RuntimeException("service died", e);
+        }
     }
 
     @Override
     public @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter) {
-        // TODO(b/36863239): forward to mTuner
-        throw new RuntimeException("Not implemented");
+        try {
+            return mTuner.getProgramList(filter);
+        } catch (RemoteException e) {
+            throw new RuntimeException("service died", e);
+        }
     }
 
     @Override
     public boolean isAnalogForced() {
-        // TODO(b/36863239): forward to mTuner
-        throw new RuntimeException("Not implemented");
+        try {
+            return mTuner.isAnalogForced();
+        } catch (RemoteException e) {
+            throw new RuntimeException("service died", e);
+        }
     }
 
     @Override
     public void setAnalogForced(boolean isForced) {
-        // TODO(b/36863239): forward to mTuner
-        throw new RuntimeException("Not implemented");
+        try {
+            mTuner.setAnalogForced(isForced);
+        } catch (RemoteException e) {
+            throw new RuntimeException("service died", e);
+        }
     }
 
     @Override
     public boolean isAntennaConnected() {
-        // TODO(b/36863239): forward to mTuner
-        throw new RuntimeException("Not implemented");
+        try {
+            return mTuner.isAntennaConnected();
+        } catch (RemoteException e) {
+            throw new RuntimeException("service died", e);
+        }
     }
 
     @Override
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index dadc5f5..083345d 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -45,7 +45,6 @@
 import android.telephony.SubscriptionManager;
 import android.util.ArrayMap;
 import android.util.Log;
-import android.util.SparseArray;
 import android.util.SparseIntArray;
 
 import com.android.internal.telephony.ITelephony;
@@ -2642,7 +2641,7 @@
 
         /**
          * Called if no network is found in the timeout time specified in
-         * {@link #requestNetwork(NetworkRequest, int, NetworkCallback)} call. This callback is not
+         * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)} call. This callback is not
          * called for the version of {@link #requestNetwork(NetworkRequest, NetworkCallback)}
          * without timeout. When this callback is invoked the associated
          * {@link NetworkRequest} will have already been removed and released, as if
@@ -2939,7 +2938,7 @@
      * This {@link NetworkRequest} will live until released via
      * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits. A
      * version of the method which takes a timeout is
-     * {@link #requestNetwork(NetworkRequest, int, NetworkCallback)}.
+     * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)}.
      * Status of the request can be followed by listening to the various
      * callbacks described in {@link NetworkCallback}.  The {@link Network}
      * can be used to direct traffic to the network.
@@ -2974,7 +2973,7 @@
      * This {@link NetworkRequest} will live until released via
      * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits. A
      * version of the method which takes a timeout is
-     * {@link #requestNetwork(NetworkRequest, int, NetworkCallback)}.
+     * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)}.
      * Status of the request can be followed by listening to the various
      * callbacks described in {@link NetworkCallback}.  The {@link Network}
      * can be used to direct traffic to the network.
diff --git a/core/java/android/net/NetworkRecommendationProvider.java b/core/java/android/net/NetworkRecommendationProvider.java
index d7b58f7..fdb4ba0 100644
--- a/core/java/android/net/NetworkRecommendationProvider.java
+++ b/core/java/android/net/NetworkRecommendationProvider.java
@@ -20,19 +20,14 @@
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.os.Build;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.IRemoteCallback;
 import android.os.RemoteException;
 import android.util.Log;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
 
-import java.util.Objects;
 import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * The base class for implementing a network recommendation provider.
@@ -55,34 +50,10 @@
 public abstract class NetworkRecommendationProvider {
     private static final String TAG = "NetworkRecProvider";
     private static final boolean VERBOSE = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
-    /** The key into the callback Bundle where the RecommendationResult will be found.
-     * @deprecated to be removed.
-     * @removed
-     */
-    public static final String EXTRA_RECOMMENDATION_RESULT =
-            "android.net.extra.RECOMMENDATION_RESULT";
-    /** The key into the callback Bundle where the sequence will be found.
-     * @deprecated to be removed.
-     * @removed
-     */
-    public static final String EXTRA_SEQUENCE = "android.net.extra.SEQUENCE";
     private final IBinder mService;
 
     /**
      * Constructs a new instance.
-     * @param handler indicates which thread to use when handling requests. Cannot be {@code null}.
-     * @deprecated use {@link #NetworkRecommendationProvider(Context, Executor)}
-     * @removed
-     */
-    public NetworkRecommendationProvider(Handler handler) {
-        if (handler == null) {
-            throw new IllegalArgumentException("The provided handler cannot be null.");
-        }
-        mService = new ServiceWrapper(handler);
-    }
-
-    /**
-     * Constructs a new instance.
      * @param context the current context instance. Cannot be {@code null}.
      * @param executor used to execute the incoming requests. Cannot be {@code null}.
      */
@@ -93,19 +64,6 @@
     }
 
     /**
-     * Invoked when a recommendation has been requested.
-     *
-     * @param request a {@link RecommendationRequest} instance containing additional
-     *                request details
-     * @param callback a {@link ResultCallback} instance. When a {@link RecommendationResult} is
-     *                 available it must be passed into
-     *                 {@link ResultCallback#onResult(RecommendationResult)}.
-     * @deprecated to be removed.
-     * @removed
-     */
-    public void onRequestRecommendation(RecommendationRequest request, ResultCallback callback) {}
-
-    /**
      * Invoked when network scores have been requested.
      * <p>
      * Use {@link NetworkScoreManager#updateScores(ScoredNetwork[])} to respond to score requests.
@@ -123,66 +81,6 @@
     }
 
     /**
-     * A callback implementing applications should invoke when a {@link RecommendationResult}
-     * is available.
-     *
-     * @deprecated to be removed.
-     * @removed
-     */
-    public static class ResultCallback {
-        private final IRemoteCallback mCallback;
-        private final int mSequence;
-        private final AtomicBoolean mCallbackRun;
-
-        /**
-         * @hide
-         */
-        @VisibleForTesting
-        public ResultCallback(IRemoteCallback callback, int sequence) {
-            mCallback = callback;
-            mSequence = sequence;
-            mCallbackRun = new AtomicBoolean(false);
-        }
-
-        /**
-         * Run the callback with the available {@link RecommendationResult}.
-         * @param result a {@link RecommendationResult} instance.
-         */
-        public void onResult(RecommendationResult result) {
-            if (VERBOSE) Log.v(TAG, "onResult(seq=" + mSequence + ")");
-            if (!mCallbackRun.compareAndSet(false, true)) {
-                throw new IllegalStateException("The callback cannot be run more than once. "
-                        + "seq=" + mSequence);
-            }
-            final Bundle data = new Bundle();
-            data.putInt(EXTRA_SEQUENCE, mSequence);
-            data.putParcelable(EXTRA_RECOMMENDATION_RESULT, result);
-            try {
-                mCallback.sendResult(data);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Callback failed for seq: " + mSequence, e);
-            }
-            if (VERBOSE) Log.v(TAG, "onResult() complete. seq=" + mSequence);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-
-            ResultCallback that = (ResultCallback) o;
-
-            return mSequence == that.mSequence
-                    && Objects.equals(mCallback, that.mCallback);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mCallback, mSequence);
-        }
-    }
-
-    /**
      * A wrapper around INetworkRecommendationProvider that dispatches to the provided Handler.
      */
     private final class ServiceWrapper extends INetworkRecommendationProvider.Stub {
@@ -190,12 +88,6 @@
         private final Executor mExecutor;
         private final Handler mHandler;
 
-        ServiceWrapper(Handler handler) {
-            mHandler = handler;
-            mExecutor = null;
-            mContext = null;
-        }
-
         ServiceWrapper(Context context, Executor executor) {
             mContext = context;
             mExecutor = executor;
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index caf7982..0d2fcd0 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -18,8 +18,8 @@
 
 import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
 import static android.net.ConnectivityManager.TYPE_ETHERNET;
-import static android.net.ConnectivityManager.TYPE_PROXY;
 import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.ConnectivityManager.TYPE_PROXY;
 import static android.net.ConnectivityManager.TYPE_WIFI;
 import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
 import static android.net.ConnectivityManager.TYPE_WIMAX;
@@ -34,8 +34,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.BackupUtils;
+import android.util.Log;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 
 import java.io.ByteArrayOutputStream;
@@ -52,14 +52,18 @@
  * @hide
  */
 public class NetworkTemplate implements Parcelable {
+    private static final String TAG = "NetworkTemplate";
+
     /**
      * Current Version of the Backup Serializer.
      */
     private static final int BACKUP_VERSION = 1;
 
     public static final int MATCH_MOBILE_ALL = 1;
+    /** @deprecated don't use this any more */
     @Deprecated
     public static final int MATCH_MOBILE_3G_LOWER = 2;
+    /** @deprecated don't use this any more */
     @Deprecated
     public static final int MATCH_MOBILE_4G = 3;
     public static final int MATCH_WIFI = 4;
@@ -69,9 +73,26 @@
     public static final int MATCH_BLUETOOTH = 8;
     public static final int MATCH_PROXY = 9;
 
+    private static boolean isKnownMatchRule(final int rule) {
+        switch (rule) {
+            case MATCH_MOBILE_ALL:
+            case MATCH_MOBILE_3G_LOWER:
+            case MATCH_MOBILE_4G:
+            case MATCH_WIFI:
+            case MATCH_ETHERNET:
+            case MATCH_MOBILE_WILDCARD:
+            case MATCH_WIFI_WILDCARD:
+            case MATCH_BLUETOOTH:
+            case MATCH_PROXY:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
     private static boolean sForceAllNetworkTypes = false;
 
-    @VisibleForTesting
     public static void forceAllNetworkTypes() {
         sForceAllNetworkTypes = true;
     }
@@ -180,6 +201,11 @@
         mSubscriberId = subscriberId;
         mMatchSubscriberIds = matchSubscriberIds;
         mNetworkId = networkId;
+
+        if (!isKnownMatchRule(matchRule)) {
+            Log.e(TAG, "Unknown network template rule " + matchRule
+                    + " will not match any identity.");
+        }
     }
 
     private NetworkTemplate(Parcel in) {
@@ -294,7 +320,9 @@
             case MATCH_PROXY:
                 return matchesProxy(ident);
             default:
-                throw new IllegalArgumentException("unknown network template");
+                // We have no idea what kind of network template we are, so we
+                // just claim not to match anything.
+                return false;
         }
     }
 
@@ -428,7 +456,7 @@
             case MATCH_PROXY:
                 return "PROXY";
             default:
-                return "UNKNOWN";
+                return "UNKNOWN(" + matchRule + ")";
         }
     }
 
@@ -496,6 +524,11 @@
         String subscriberId = BackupUtils.readString(in);
         String networkId = BackupUtils.readString(in);
 
+        if (!isKnownMatchRule(matchRule)) {
+            throw new BackupUtils.BadVersionException(
+                    "Restored network template contains unknown match rule " + matchRule);
+        }
+
         return new NetworkTemplate(matchRule, subscriberId, networkId);
     }
 }
diff --git a/core/java/android/net/RecommendationRequest.java b/core/java/android/net/RecommendationRequest.java
deleted file mode 100644
index 21641d9..0000000
--- a/core/java/android/net/RecommendationRequest.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.net;
-
-
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * A request for a network recommendation.
- *
- * @see {@link NetworkScoreManager#requestRecommendation(RecommendationRequest)}.
- * @hide
- * @deprecated to be removed.
- * @removed
- */
-public final class RecommendationRequest implements Parcelable {
-    private final ScanResult[] mScanResults;
-    private final WifiConfiguration mDefaultConfig;
-    private WifiConfiguration mConnectedConfig;
-    private WifiConfiguration[] mConnectableConfigs;
-    private final int mLastSelectedNetworkId;
-    private final long mLastSelectedNetworkTimestamp;
-
-    /**
-     * Builder class for constructing {@link RecommendationRequest} instances.
-     * @hide
-     * @deprecated to be removed.
-     * @removed
-     */
-    public static final class Builder {
-        private ScanResult[] mScanResults;
-        private WifiConfiguration mDefaultConfig;
-        private WifiConfiguration mConnectedConfig;
-        private WifiConfiguration[] mConnectableConfigs;
-        private int mLastSelectedNetworkId = -1;
-        private long mLastSelectedTimestamp;
-
-        public Builder setScanResults(ScanResult[] scanResults) {
-            mScanResults = scanResults;
-            return this;
-        }
-
-        /**
-         * @param config the {@link WifiConfiguration} to return if no recommendation is available.
-         * @return this
-         */
-        public Builder setDefaultWifiConfig(WifiConfiguration config) {
-            this.mDefaultConfig = config;
-            return this;
-        }
-
-        /**
-         * @param config the {@link WifiConfiguration} of the connected network at the time the
-         *               this request was made.
-         * @return this
-         */
-        public Builder setConnectedWifiConfig(WifiConfiguration config) {
-            this.mConnectedConfig = config;
-            return this;
-        }
-
-        /**
-         * @param connectableConfigs the set of saved {@link WifiConfiguration}s that can be
-         *                           connected to based on the current set of {@link ScanResult}s.
-         * @return this
-         */
-        public Builder setConnectableConfigs(WifiConfiguration[] connectableConfigs) {
-            this.mConnectableConfigs = connectableConfigs;
-            return this;
-        }
-
-        /**
-         * @param networkId The {@link WifiConfiguration#networkId} of the last user selected
-         *                  network.
-         * @param timestamp The {@link android.os.SystemClock#elapsedRealtime()} when the user
-         *                  selected {@code networkId}.
-         * @return this
-         */
-        public Builder setLastSelectedNetwork(int networkId, long timestamp) {
-            this.mLastSelectedNetworkId = networkId;
-            this.mLastSelectedTimestamp = timestamp;
-            return this;
-        }
-
-        /**
-         * @return a new {@link RecommendationRequest} instance
-         */
-        public RecommendationRequest build() {
-            return new RecommendationRequest(mScanResults, mDefaultConfig, mConnectedConfig,
-                    mConnectableConfigs, mLastSelectedNetworkId, mLastSelectedTimestamp);
-        }
-    }
-
-    /**
-     * @return the array of {@link ScanResult}s the recommendation must be constrained to i.e. if a
-     *         non-null wifi config recommendation is returned then it must be able to connect to
-     *         one of the networks in the results list.
-     *
-     *         If the array is {@code null} or empty then there is no constraint.
-     */
-    public ScanResult[] getScanResults() {
-        return mScanResults;
-    }
-
-    /**
-     * @return the {@link WifiConfiguration} to return if no recommendation is available.
-     */
-    public WifiConfiguration getDefaultWifiConfig() {
-        return mDefaultConfig;
-    }
-
-    /**
-     * @return the {@link WifiConfiguration} of the connected network at the time the this request
-     *         was made.
-     */
-    public WifiConfiguration getConnectedConfig() {
-        return mConnectedConfig;
-    }
-
-    /**
-     * @return the set of saved {@link WifiConfiguration}s that can be connected to based on the
-     *         current set of {@link ScanResult}s.
-     */
-    public WifiConfiguration[] getConnectableConfigs() {
-        return mConnectableConfigs;
-    }
-
-    /**
-     * @param connectedConfig the {@link WifiConfiguration} of the connected network at the time
-     *                        the this request was made.
-     */
-    public void setConnectedConfig(WifiConfiguration connectedConfig) {
-        mConnectedConfig = connectedConfig;
-    }
-
-    /**
-     * @param connectableConfigs the set of saved {@link WifiConfiguration}s that can be connected
-     *                           to based on the current set of {@link ScanResult}s.
-     */
-    public void setConnectableConfigs(WifiConfiguration[] connectableConfigs) {
-        mConnectableConfigs = connectableConfigs;
-    }
-
-    /**
-     * @return The {@link WifiConfiguration#networkId} of the last user selected network.
-     *         {@code -1} if not set.
-     */
-    public int getLastSelectedNetworkId() {
-        return mLastSelectedNetworkId;
-    }
-
-    /**
-     * @return The {@link android.os.SystemClock#elapsedRealtime()} when the user selected
-     *         {@link #getLastSelectedNetworkId()}. {@code 0} if not set.
-     */
-    public long getLastSelectedNetworkTimestamp() {
-        return mLastSelectedNetworkTimestamp;
-    }
-
-    @VisibleForTesting
-    RecommendationRequest(ScanResult[] scanResults,
-            WifiConfiguration defaultWifiConfig,
-            WifiConfiguration connectedWifiConfig,
-            WifiConfiguration[] connectableConfigs,
-            int lastSelectedNetworkId,
-            long lastSelectedNetworkTimestamp) {
-        mScanResults = scanResults;
-        mDefaultConfig = defaultWifiConfig;
-        mConnectedConfig = connectedWifiConfig;
-        mConnectableConfigs = connectableConfigs;
-        mLastSelectedNetworkId = lastSelectedNetworkId;
-        mLastSelectedNetworkTimestamp = lastSelectedNetworkTimestamp;
-    }
-
-    protected RecommendationRequest(Parcel in) {
-        final int resultCount = in.readInt();
-        if (resultCount > 0) {
-            mScanResults = new ScanResult[resultCount];
-            final ClassLoader classLoader = ScanResult.class.getClassLoader();
-            for (int i = 0; i < resultCount; i++) {
-                mScanResults[i] = in.readParcelable(classLoader);
-            }
-        } else {
-            mScanResults = null;
-        }
-
-        mDefaultConfig = in.readParcelable(WifiConfiguration.class.getClassLoader());
-        mConnectedConfig = in.readParcelable(WifiConfiguration.class.getClassLoader());
-
-        final int configCount = in.readInt();
-        if (configCount > 0) {
-            mConnectableConfigs = new WifiConfiguration[configCount];
-            final ClassLoader classLoader = WifiConfiguration.class.getClassLoader();
-            for (int i = 0; i < configCount; i++) {
-                mConnectableConfigs[i] = in.readParcelable(classLoader);
-            }
-        } else {
-            mConnectableConfigs = null;
-        }
-
-        mLastSelectedNetworkId = in.readInt();
-        mLastSelectedNetworkTimestamp = in.readLong();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        if (mScanResults != null) {
-            dest.writeInt(mScanResults.length);
-            for (int i = 0; i < mScanResults.length; i++) {
-                dest.writeParcelable(mScanResults[i], flags);
-            }
-        } else {
-            dest.writeInt(0);
-        }
-
-        dest.writeParcelable(mDefaultConfig, flags);
-        dest.writeParcelable(mConnectedConfig, flags);
-
-        if (mConnectableConfigs != null) {
-            dest.writeInt(mConnectableConfigs.length);
-            for (int i = 0; i < mConnectableConfigs.length; i++) {
-                dest.writeParcelable(mConnectableConfigs[i], flags);
-            }
-        } else {
-            dest.writeInt(0);
-        }
-
-        dest.writeInt(mLastSelectedNetworkId);
-        dest.writeLong(mLastSelectedNetworkTimestamp);
-    }
-
-    public static final Creator<RecommendationRequest> CREATOR =
-            new Creator<RecommendationRequest>() {
-                @Override
-                public RecommendationRequest createFromParcel(Parcel in) {
-                    return new RecommendationRequest(in);
-                }
-
-                @Override
-                public RecommendationRequest[] newArray(int size) {
-                    return new RecommendationRequest[size];
-                }
-            };
-}
diff --git a/core/java/android/net/RecommendationResult.java b/core/java/android/net/RecommendationResult.java
deleted file mode 100644
index d66dd22..0000000
--- a/core/java/android/net/RecommendationResult.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.net;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.wifi.WifiConfiguration;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.internal.util.Preconditions;
-
-/**
- * The result of a network recommendation.
- *
- * @see {@link NetworkScoreManager#requestRecommendation(RecommendationRequest)}.
- * @hide
- * @deprecated to be removed.
- * @removed
- */
-public final class RecommendationResult implements Parcelable {
-    private final WifiConfiguration mWifiConfiguration;
-
-    /**
-     * Create a {@link RecommendationResult} that indicates that no network connection should be
-     * attempted at this time.
-     *
-     * @return a {@link RecommendationResult}
-     */
-    public static RecommendationResult createDoNotConnectRecommendation() {
-        return new RecommendationResult((WifiConfiguration) null);
-    }
-
-    /**
-     * Create a {@link RecommendationResult} that indicates that a connection attempt should be
-     * made for the given Wi-Fi network.
-     *
-     * @param wifiConfiguration {@link WifiConfiguration} with at least SSID and BSSID set.
-     * @return a {@link RecommendationResult}
-     */
-    public static RecommendationResult createConnectRecommendation(
-            @NonNull WifiConfiguration wifiConfiguration) {
-        Preconditions.checkNotNull(wifiConfiguration, "wifiConfiguration must not be null");
-        Preconditions.checkNotNull(wifiConfiguration.SSID, "SSID must not be null");
-        Preconditions.checkNotNull(wifiConfiguration.BSSID, "BSSID must not be null");
-        return new RecommendationResult(wifiConfiguration);
-    }
-
-    private RecommendationResult(@Nullable WifiConfiguration wifiConfiguration) {
-        mWifiConfiguration = wifiConfiguration;
-    }
-
-    private RecommendationResult(Parcel in) {
-        mWifiConfiguration = in.readParcelable(WifiConfiguration.class.getClassLoader());
-    }
-
-    /**
-     * @return {@code true} if a network recommendation exists. {@code false} indicates that
-     *         no connection should be attempted at this time.
-     */
-    public boolean hasRecommendation() {
-        return mWifiConfiguration != null;
-    }
-
-    /**
-     * @return The recommended {@link WifiConfiguration} to connect to. A {@code null} value
-     *         is returned if {@link #hasRecommendation} returns {@code false}.
-     */
-    @Nullable public WifiConfiguration getWifiConfiguration() {
-        return mWifiConfiguration;
-    }
-
-    @Override
-    public String toString() {
-      return "RecommendationResult{" +
-          "mWifiConfiguration=" + mWifiConfiguration +
-          "}";
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeParcelable(mWifiConfiguration, flags);
-    }
-
-    public static final Creator<RecommendationResult> CREATOR =
-            new Creator<RecommendationResult>() {
-                @Override
-                public RecommendationResult createFromParcel(Parcel in) {
-                    return new RecommendationResult(in);
-                }
-
-                @Override
-                public RecommendationResult[] newArray(int size) {
-                    return new RecommendationResult[size];
-                }
-            };
-}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index cabe24f..499d6bb 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -157,6 +157,11 @@
     public static final int BLUETOOTH_SCAN_ON = 19;
 
     /**
+     * A constant indicating an aggregated partial wake lock timer.
+     */
+    public static final int AGGREGATED_WAKE_TYPE_PARTIAL = 20;
+
+    /**
      * Include all of the data in the stats, including previously saved data.
      */
     public static final int STATS_SINCE_CHARGED = 0;
@@ -185,6 +190,7 @@
      *   - Background timers and counters for: Sensor, BluetoothScan, WifiScan, Jobs, Syncs.
      * New in version 21:
      *   - Actual (not just apportioned) Wakelock time is also recorded.
+     *   - Aggregated partial wakelock time (per uid, instead of per wakelock) is recorded.
      */
     static final String CHECKIN_VERSION = "21";
 
@@ -216,6 +222,10 @@
     // window totalTime,  'w', count, current duration, max duration, total duration
     // [Currently, full and window wakelocks have durations current = max = total = -1]
     private static final String WAKELOCK_DATA = "wl";
+    // awl line is:
+    // BATTERY_STATS_CHECKIN_VERSION, uid, which, "awl",
+    // cumulative partial wakelock duration, cumulative background partial wakelock duration
+    private static final String AGGREGATED_WAKELOCK_DATA = "awl";
     private static final String SYNC_DATA = "sy";
     private static final String JOB_DATA = "jb";
     private static final String KERNEL_WAKELOCK_DATA = "kwl";
@@ -485,6 +495,13 @@
         }
 
         /**
+         * The cumulative time the uid spent holding any partial wakelocks. This will generally
+         * differ from summing over the Wakelocks in getWakelockStats since the latter may have
+         * wakelocks that overlap in time (and therefore over-counts).
+         */
+        public abstract Timer getAggregatedPartialWakelockTimer();
+
+        /**
          * Returns a mapping containing sensor statistics.
          *
          * @return a Map from Integer sensor ids to Uid.Sensor objects.
@@ -495,7 +512,7 @@
          * Returns a mapping containing active process data.
          */
         public abstract SparseArray<? extends Pid> getPidStats();
-        
+
         /**
          * Returns a mapping containing process statistics.
          *
@@ -609,7 +626,7 @@
         static final String[] USER_ACTIVITY_TYPES = {
             "other", "button", "touch", "accessibility"
         };
-        
+
         public static final int NUM_USER_ACTIVITY_TYPES = 4;
 
         public abstract void noteUserActivityLocked(int type);
@@ -1189,7 +1206,6 @@
 
         // Platform-level low power state stats
         public String statPlatformIdleState;
-        public String statSubsystemPowerState;
 
         public HistoryStepDetails() {
             clear();
@@ -1221,7 +1237,6 @@
             out.writeInt(statSoftIrqTime);
             out.writeInt(statIdlTime);
             out.writeString(statPlatformIdleState);
-            out.writeString(statSubsystemPowerState);
         }
 
         public void readFromParcel(Parcel in) {
@@ -1243,7 +1258,6 @@
             statSoftIrqTime = in.readInt();
             statIdlTime = in.readInt();
             statPlatformIdleState = in.readString();
-            statSubsystemPowerState = in.readString();
         }
     }
 
@@ -1262,7 +1276,7 @@
         public static final byte CMD_SHUTDOWN = 8;
 
         public byte cmd = CMD_NULL;
-        
+
         /**
          * Return whether the command code is a delta data update.
          */
@@ -1274,13 +1288,13 @@
         public byte batteryStatus;
         public byte batteryHealth;
         public byte batteryPlugType;
-        
+
         public short batteryTemperature;
         public char batteryVoltage;
 
         // The charge of the battery in micro-Ampere-hours.
         public int batteryChargeUAh;
-        
+
         // Constants from SCREEN_BRIGHTNESS_*
         public static final int STATE_BRIGHTNESS_SHIFT = 0;
         public static final int STATE_BRIGHTNESS_MASK = 0x7;
@@ -1461,13 +1475,13 @@
 
         public HistoryItem() {
         }
-        
+
         public HistoryItem(long time, Parcel src) {
             this.time = time;
             numReadInts = 2;
             readFromParcel(src);
         }
-        
+
         public int describeContents() {
             return 0;
         }
@@ -1563,7 +1577,7 @@
             eventCode = EVENT_NONE;
             eventTag = null;
         }
-        
+
         public void setTo(HistoryItem o) {
             time = o.time;
             cmd = o.cmd;
@@ -1717,7 +1731,7 @@
         public final String shortName;
         public final String[] values;
         public final String[] shortValues;
-        
+
         public BitDescription(int mask, String name, String shortName) {
             this.mask = mask;
             this.shift = -1;
@@ -1726,7 +1740,7 @@
             this.values = null;
             this.shortValues = null;
         }
-        
+
         public BitDescription(int mask, int shift, String name, String shortName,
                 String[] values, String[] shortValues) {
             this.mask = mask;
@@ -1774,20 +1788,20 @@
      * Return the base time offset for the battery history.
      */
     public abstract long getHistoryBaseTime();
-    
+
     /**
      * Returns the number of times the device has been started.
      */
     public abstract int getStartCount();
-    
+
     /**
      * Returns the time in microseconds that the screen has been on while the device was
      * running on battery.
-     * 
+     *
      * {@hide}
      */
     public abstract long getScreenOnTime(long elapsedRealtimeUs, int which);
-    
+
     /**
      * Returns the number of times the screen was turned on.
      *
@@ -1802,11 +1816,11 @@
     public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
     public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
     public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
-    
+
     static final String[] SCREEN_BRIGHTNESS_NAMES = {
         "dark", "dim", "medium", "light", "bright"
     };
-    
+
     static final String[] SCREEN_BRIGHTNESS_SHORT_NAMES = {
         "0", "1", "2", "3", "4"
     };
@@ -1816,7 +1830,7 @@
     /**
      * Returns the time in microseconds that the screen has been on with
      * the given brightness
-     * 
+     *
      * {@hide}
      */
     public abstract long getScreenBrightnessTime(int brightnessBin,
@@ -1900,11 +1914,11 @@
     /**
      * Returns the time in microseconds that the phone has been on while the device was
      * running on battery.
-     * 
+     *
      * {@hide}
      */
     public abstract long getPhoneOnTime(long elapsedRealtimeUs, int which);
-    
+
     /**
      * Returns the number of times a phone call was activated.
      *
@@ -1915,7 +1929,7 @@
     /**
      * Returns the time in microseconds that the phone has been running with
      * the given signal strength.
-     * 
+     *
      * {@hide}
      */
     public abstract long getPhoneSignalStrengthTime(int strengthBin,
@@ -1932,7 +1946,7 @@
 
     /**
      * Returns the number of times the phone has entered the given signal strength.
-     * 
+     *
      * {@hide}
      */
     public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
@@ -2000,13 +2014,13 @@
         "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
         "ehrpd", "hspap", "other"
     };
-    
+
     public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
-    
+
     /**
      * Returns the time in microseconds that the phone has been running with
      * the given data connection.
-     * 
+     *
      * {@hide}
      */
     public abstract long getPhoneDataConnectionTime(int dataType,
@@ -2015,7 +2029,7 @@
     /**
      * Returns the number of times the phone has entered the given data
      * connection type.
-     * 
+     *
      * {@hide}
      */
     public abstract int getPhoneDataConnectionCount(int dataType, int which);
@@ -2134,7 +2148,7 @@
     /**
      * Returns the time in microseconds that wifi has been on while the device was
      * running on battery.
-     * 
+     *
      * {@hide}
      */
     public abstract long getWifiOnTime(long elapsedRealtimeUs, int which);
@@ -2325,7 +2339,7 @@
      * Return whether we are currently running on battery.
      */
     public abstract boolean getIsOnBattery();
-    
+
     /**
      * Returns a SparseArray containing the statistics for each uid.
      */
@@ -2344,13 +2358,13 @@
      * @param curTime the amount of elapsed realtime in microseconds.
      */
     public abstract long getBatteryRealtime(long curTime);
-    
+
     /**
      * Returns the battery percentage level at the last time the device was unplugged from power, or
-     * the last time it booted on battery power. 
+     * the last time it booted on battery power.
      */
     public abstract int getDischargeStartLevel();
-    
+
     /**
      * Returns the current battery percentage level if we are in a discharge cycle, otherwise
      * returns the level at the last plug event.
@@ -2646,7 +2660,7 @@
 
     final String formatBytesLocked(long bytes) {
         mFormatBuilder.setLength(0);
-        
+
         if (bytes < BYTES_PER_KB) {
             return bytes + "B";
         } else if (bytes < BYTES_PER_MB) {
@@ -2776,10 +2790,10 @@
         }
         return false;
     }
-    
+
     /**
      * Checkin version of wakelock printer. Prints simple comma-separated list.
-     * 
+     *
      * @param sb a StringBuilder object.
      * @param timer a Timer object contining the wakelock times.
      * @param elapsedRealtimeUs the current time in microseconds.
@@ -2834,13 +2848,13 @@
 
     /**
      * Dump a comma-separated line of values for terse checkin mode.
-     * 
+     *
      * @param pw the PageWriter to dump log to
      * @param category category of data (e.g. "total", "last", "unplugged", "current" )
      * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
      * @param args type-dependent data arguments
      */
-    private static final void dumpLine(PrintWriter pw, int uid, String category, String type, 
+    private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
            Object... args ) {
         dumpLineHeader(pw, uid, category, type);
         for (Object arg : args) {
@@ -3017,7 +3031,7 @@
 
     /**
      * Checkin server version of dump to produce more compact, computer-readable log.
-     * 
+     *
      * NOTE: all times are expressed in 'ms'.
      */
     public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid,
@@ -3050,10 +3064,10 @@
                 .getCountLocked(which);
 
         final StringBuilder sb = new StringBuilder(128);
-        
+
         final SparseArray<? extends Uid> uidStats = getUidStats();
         final int NU = uidStats.size();
-        
+
         final String category = STAT_NAMES[which];
 
         // Dump "battery" stat
@@ -3066,11 +3080,11 @@
                 getEstimatedBatteryCapacity(),
                 getMinLearnedBatteryCapacity(), getMaxLearnedBatteryCapacity());
 
-        
+
         // Calculate wakelock times across all uids.
         long fullWakeLockTimeTotal = 0;
         long partialWakeLockTimeTotal = 0;
-        
+
         for (int iu = 0; iu < NU; iu++) {
             final Uid u = uidStats.valueAt(iu);
 
@@ -3141,14 +3155,14 @@
                 getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which),
                 getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT),
                 getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
-        
+
         // Dump screen brightness stats
         Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
             args[i] = getScreenBrightnessTime(i, rawRealtime, which) / 1000;
         }
         dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
-        
+
         // Dump signal strength stats
         args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
@@ -3210,7 +3224,7 @@
             dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
                     getDischargeCurrentLevel());
         }
-        
+
         if (which == STATS_SINCE_UNPLUGGED) {
             dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
                     getDischargeStartLevel()-getDischargeCurrentLevel(),
@@ -3224,7 +3238,7 @@
                     getDischargeAmountScreenOffSinceCharge(),
                     dischargeCount / 1000, dischargeScreenOffCount / 1000);
         }
-        
+
         if (reqUid < 0) {
             final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
             if (kernelWakelocks.size() > 0) {
@@ -3247,7 +3261,7 @@
                 }
             }
         }
-        
+
         final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
         helper.create(this);
         helper.refreshStats(which, UserHandle.USER_ALL);
@@ -3437,7 +3451,17 @@
                     dumpLine(pw, uid /* uid */, category, USER_ACTIVITY_DATA, args);
                 }
             }
-            
+
+            if (u.getAggregatedPartialWakelockTimer() != null) {
+                final Timer timer = u.getAggregatedPartialWakelockTimer();
+                // Convert from microseconds to milliseconds with rounding
+                final long totTimeMs = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
+                final Timer bgTimer = timer.getSubTimer();
+                final long bgTimeMs = bgTimer != null ?
+                        (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : 0;
+                dumpLine(pw, uid, category, AGGREGATED_WAKELOCK_DATA, totTimeMs, bgTimeMs);
+            }
+
             final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
             for (int iw=wakelocks.size()-1; iw>=0; iw--) {
                 final Uid.Wakelock wl = wakelocks.valueAt(iw);
@@ -3669,7 +3693,7 @@
         final long chargeTimeRemaining = computeChargeTimeRemaining(rawRealtime);
 
         final StringBuilder sb = new StringBuilder(128);
-        
+
         final SparseArray<? extends Uid> uidStats = getUidStats();
         final int NU = uidStats.size();
 
@@ -3935,7 +3959,7 @@
                 }
             }
         }
-        
+
         final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
         final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
         final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
@@ -4164,15 +4188,15 @@
         if (which == STATS_SINCE_UNPLUGGED) {
             if (getIsOnBattery()) {
                 pw.print(prefix); pw.println("  Device is currently unplugged");
-                pw.print(prefix); pw.print("    Discharge cycle start level: "); 
+                pw.print(prefix); pw.print("    Discharge cycle start level: ");
                         pw.println(getDischargeStartLevel());
                 pw.print(prefix); pw.print("    Discharge cycle current level: ");
                         pw.println(getDischargeCurrentLevel());
             } else {
                 pw.print(prefix); pw.println("  Device is currently plugged into power");
-                pw.print(prefix); pw.print("    Last discharge cycle start level: "); 
+                pw.print(prefix); pw.print("    Last discharge cycle start level: ");
                         pw.println(getDischargeStartLevel());
-                pw.print(prefix); pw.print("    Last discharge cycle end level: "); 
+                pw.print(prefix); pw.print("    Last discharge cycle end level: ");
                         pw.println(getDischargeCurrentLevel());
             }
             pw.print(prefix); pw.print("    Amount discharged while screen on: ");
@@ -4453,7 +4477,7 @@
             if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
                 continue;
             }
-            
+
             final Uid u = uidStats.valueAt(iu);
 
             pw.print(prefix);
@@ -4541,7 +4565,7 @@
                         formatTimeMs(sb, uidWifiRunningTime / 1000);
                         sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
                                 whichBatteryRealtime)); sb.append(")\n");
-                sb.append(prefix); sb.append("    Full Wifi Lock: "); 
+                sb.append(prefix); sb.append("    Full Wifi Lock: ");
                         formatTimeMs(sb, fullWifiLockOnTime / 1000);
                         sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
                                 whichBatteryRealtime)); sb.append(")\n");
@@ -4693,8 +4717,23 @@
                         rawRealtime, which);
             }
             if (countWakelock > 1) {
-                if (totalFullWakelock != 0 || totalPartialWakelock != 0
-                        || totalWindowWakelock != 0) {
+                // get unpooled partial wakelock quantities (unlike totalPartialWakelock, which is
+                // pooled and therefore just a lower bound)
+                long actualTotalPartialWakelock = 0;
+                long actualBgPartialWakelock = 0;
+                if (u.getAggregatedPartialWakelockTimer() != null) {
+                    final Timer aggTimer = u.getAggregatedPartialWakelockTimer();
+                    // Convert from microseconds to milliseconds with rounding
+                    actualTotalPartialWakelock =
+                            (aggTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
+                    final Timer bgAggTimer = aggTimer.getSubTimer();
+                    actualBgPartialWakelock = bgAggTimer != null ?
+                            (bgAggTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : 0;
+                }
+
+                if (actualTotalPartialWakelock != 0 || actualBgPartialWakelock != 0 ||
+                        totalFullWakelock != 0 || totalPartialWakelock != 0 ||
+                        totalWindowWakelock != 0) {
                     sb.setLength(0);
                     sb.append(prefix);
                     sb.append("    TOTAL wake: ");
@@ -4710,7 +4749,23 @@
                         }
                         needComma = true;
                         formatTimeMs(sb, totalPartialWakelock);
-                        sb.append("partial");
+                        sb.append("blamed partial");
+                    }
+                    if (actualTotalPartialWakelock != 0) {
+                        if (needComma) {
+                            sb.append(", ");
+                        }
+                        needComma = true;
+                        formatTimeMs(sb, actualTotalPartialWakelock);
+                        sb.append("actual partial");
+                    }
+                    if (actualBgPartialWakelock != 0) {
+                        if (needComma) {
+                            sb.append(", ");
+                        }
+                        needComma = true;
+                        formatTimeMs(sb, actualBgPartialWakelock);
+                        sb.append("actual background partial");
                     }
                     if (totalWindowWakelock != 0) {
                         if (needComma) {
@@ -5390,10 +5445,6 @@
                         pw.print(", PlatformIdleStat ");
                         pw.print(rec.stepDetails.statPlatformIdleState);
                         pw.println();
-
-                        pw.print(", SubsystemPowerState ");
-                        pw.print(rec.stepDetails.statSubsystemPowerState);
-                        pw.println();
                     } else {
                         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
                         pw.print(HISTORY_DATA); pw.print(",0,Dcpu=");
@@ -5431,11 +5482,6 @@
                             pw.print(rec.stepDetails.statPlatformIdleState);
                         }
                         pw.println();
-
-                        if (rec.stepDetails.statSubsystemPowerState != null) {
-                            pw.print(rec.stepDetails.statSubsystemPowerState);
-                        }
-                        pw.println();
                     }
                 }
                 oldState = rec.states;
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index f4a9ef6..68a81ca 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -430,13 +430,7 @@
      * @param size The new number of bytes in the Parcel.
      */
     public final void setDataSize(int size) {
-        // STOPSHIP: Try/catch for exception is for temporary debug. Remove once bug resolved
-        try {
-            updateNativeSize(nativeSetDataSize(mNativePtr, size));
-        } catch (IllegalArgumentException iae) {
-            Log.e(TAG,"Caught Exception representing a known bug in Parcel",iae);
-            Log.wtfStack(TAG, "This flow is using SetDataSize incorrectly");
-        }
+        updateNativeSize(nativeSetDataSize(mNativePtr, size));
     }
 
     /**
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 3212139..c091420 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -547,7 +547,8 @@
      * Converts a string representing a file mode, such as "rw", into a bitmask suitable for use
      * with {@link #open}.
      * <p>
-     * @param mode The string representation of the file mode.
+     * @param mode The string representation of the file mode. Can be "r", "w", "wt", "wa", "rw"
+     *             or "rwt".
      * @return A bitmask representing the given file mode.
      * @throws IllegalArgumentException if the given string does not match a known file mode.
      */
diff --git a/core/java/android/os/ProxyFileDescriptorCallback.java b/core/java/android/os/ProxyFileDescriptorCallback.java
index e69fb55..9f56802 100644
--- a/core/java/android/os/ProxyFileDescriptorCallback.java
+++ b/core/java/android/os/ProxyFileDescriptorCallback.java
@@ -22,7 +22,23 @@
 /**
  * Callback that handles file system requests from ProxyFileDescriptor.
  *
- * @see android.os.storage.StorageManager#openProxyFileDescriptor(int, ProxyFileDescriptorCallback)
+ * All callback methods except for onRelease should throw {@link android.system.ErrnoException}
+ * with proper errno on errors. See
+ * <a href="http://man7.org/linux/man-pages/man3/errno.3.html">errno(3)</a> and
+ * {@link android.system.OsConstants}.
+ *
+ * Typical errnos are
+ *
+ * <ul>
+ * <li>{@link android.system.OsConstants#EIO} for general I/O issues
+ * <li>{@link android.system.OsConstants#ENOENT} when the file is not found
+ * <li>{@link android.system.OsConstants#EBADF} if the file doesn't allow read/write operations
+ *     based on how it was opened.  (For example, trying to write a file that was opened read-only.)
+ * <li>{@link android.system.OsConstants#ENOSPC} if you cannot handle a write operation to
+ *     space/quota limitations.
+ * </ul>
+ * @see android.os.storage.StorageManager#openProxyFileDescriptor(int, ProxyFileDescriptorCallback,
+ *     Handler)
  */
 public abstract class ProxyFileDescriptorCallback {
     /**
diff --git a/core/java/android/os/UserManagerInternal.java b/core/java/android/os/UserManagerInternal.java
index 97da588..17f00c2 100644
--- a/core/java/android/os/UserManagerInternal.java
+++ b/core/java/android/os/UserManagerInternal.java
@@ -167,4 +167,12 @@
      * Remove user's running state
      */
     public abstract void removeUserState(int userId);
+
+    /**
+     * Returns an array of user ids. This array is cached in UserManagerService and passed as a
+     * reference, so do not modify the returned array.
+     *
+     * @return the array of user ids.
+     */
+    public abstract int[] getUserIds();
 }
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 2cc4b71..92f7f31 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -295,4 +295,5 @@
     long getCacheSizeBytes(String volumeUuid, int uid) = 76;
     long getAllocatableBytes(String volumeUuid, int flags) = 77;
     void allocateBytes(String volumeUuid, long bytes, int flags) = 78;
+    void secdiscard(in String path) = 79;
 }
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index bd43d6a..f361c54 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -1252,6 +1252,15 @@
     }
 
     /** {@hide} */
+    public void secdiscard(String path) {
+        try {
+            mStorageManager.secdiscard(path);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** {@hide} */
     public static boolean isUserKeyUnlocked(int userId) {
         if (sStorageManager == null) {
             sStorageManager = IStorageManager.Stub
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 2a83c4b..3eef31a 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -655,8 +655,12 @@
      * <p>
      * Your provider should return a reliable {@link ParcelFileDescriptor} to
      * detect when the remote caller has finished reading or writing the
-     * document. You may return a pipe or socket pair if the mode is exclusively
-     * "r" or "w", but complex modes like "rw" imply a normal file on disk that
+     * document.
+     * <p>
+     * Mode "r" should always be supported. Provider should throw
+     * {@link UnsupportedOperationException} if the passing mode is not supported.
+     * You may return a pipe or socket pair if the mode is exclusively "r" or
+     * "w", but complex modes like "rw" imply a normal file on disk that
      * supports seeking.
      * <p>
      * If you block while downloading content, you should periodically check
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e32d884..52718fc 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6767,20 +6767,6 @@
         public static final String ASSIST_GESTURE_SENSITIVITY = "assist_gesture_sensitivity";
 
         /**
-         * Whether the assist gesture should be enabled during sleep
-         *
-         * @hide
-         */
-        public static final String ASSIST_GESTURE_ENABLED_SLEEP = "assist_gesture_enabled_sleep";
-
-        /**
-         * Whether assist gesture should be enabled in keyguard
-         *
-         * @hide
-         */
-        public static final String ASSIST_GESTURE_ENABLED_KEYGUARD = "assist_gesture_enabled_keyguard";
-
-        /**
          * Control whether Night display is currently activated.
          * @hide
          */
@@ -7055,8 +7041,6 @@
             NIGHT_DISPLAY_CUSTOM_END_TIME,
             NIGHT_DISPLAY_COLOR_TEMPERATURE,
             NIGHT_DISPLAY_AUTO_MODE,
-            NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
-            NIGHT_DISPLAY_ACTIVATED,
             SYNC_PARENT_SOUNDS,
             CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
             CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
@@ -9157,6 +9141,23 @@
         public static final String BATTERY_SAVER_CONSTANTS = "battery_saver_constants";
 
         /**
+         * Battery anomaly detection specific settings
+         * This is encoded as a key=value list, separated by commas. Ex:
+         *
+         * "anomaly_detection_enabled=true,wakelock_threshold=2000"
+         *
+         * The following keys are supported:
+         *
+         * <pre>
+         * anomaly_detection_enabled       (boolean)
+         * wakelock_enabled                (boolean)
+         * wakelock_threshold              (long)
+         * </pre>
+         * @hide
+         */
+        public static final String ANOMALY_DETECTION_CONSTANTS = "anomaly_detection_constants";
+
+        /**
          * App standby (app idle) specific settings.
          * This is encoded as a key=value list, separated by commas. Ex:
          *
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 585f882..3baadd4 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -1943,6 +1943,16 @@
         return charSequence;
     }
 
+    /**
+     * Prepends {@code start} and appends {@code end} to a given {@link StringBuilder}
+     *
+     * @hide
+     */
+    public static void wrap(StringBuilder builder, String start, String end) {
+        builder.insert(0, start);
+        builder.append(end);
+    }
+
     private static Object sLock = new Object();
 
     private static char[] sTemp = null;
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 2ade9b5..2c33b60 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -245,6 +245,7 @@
         super.onAttachedToWindow();
 
         getViewRootImpl().addWindowStoppedCallback(this);
+        mWindowStopped = false;
 
         mParent.requestTransparentRegion(this);
         mViewVisibility = getVisibility() == VISIBLE;
@@ -855,7 +856,7 @@
      */
     @Deprecated
     public void setWindowType(int type) {
-        if (getContext().getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.N_MR1) {
+        if (getContext().getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O) {
             throw new UnsupportedOperationException(
                     "SurfaceView#setWindowType() has never been a public API.");
         }
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index c66bf874..4402fb1 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -29,6 +29,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemProperties;
 import android.os.Trace;
 import android.util.Log;
 import android.view.Surface.OutOfResourcesException;
@@ -188,6 +189,11 @@
     public static final String DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY =
             "debug.hwui.show_non_rect_clip";
 
+    static {
+        // Try to check OpenGL support early if possible.
+        isAvailable();
+    }
+
     /**
      * A process can set this flag to false to prevent the use of threaded
      * rendering.
@@ -227,8 +233,7 @@
         sTrimForeground = true;
     }
 
-    private static native boolean nSupportsOpenGL();
-    private static boolean sSupportsOpenGL = nSupportsOpenGL();
+    private static Boolean sSupportsOpenGL;
 
     /**
      * Indicates whether threaded rendering is available under any form for
@@ -238,7 +243,24 @@
      *         false otherwise
      */
     public static boolean isAvailable() {
-        return sSupportsOpenGL;
+        if (sSupportsOpenGL != null) {
+            return sSupportsOpenGL.booleanValue();
+        }
+        if (SystemProperties.getInt("ro.kernel.qemu", 0) == 0) {
+            // Device is not an emulator.
+            sSupportsOpenGL = true;
+            return true;
+        }
+        int qemu_gles = SystemProperties.getInt("qemu.gles", -1);
+        if (qemu_gles == -1) {
+            // In this case, the value of the qemu.gles property is not ready
+            // because the SurfaceFlinger service may not start at this point.
+            return false;
+        }
+        // In the emulator this property will be set > 0 when OpenGL ES 2.0 is
+        // enabled, 0 otherwise. On old emulator versions it will be undefined.
+        sSupportsOpenGL = qemu_gles > 0;
+        return sSupportsOpenGL.booleanValue();
     }
 
     /**
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 14e8185..0680acf 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2032,8 +2032,6 @@
 
     private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
 
-    SendViewStateChangedAccessibilityEvent mSendViewStateChangedAccessibilityEvent;
-
     /**
      * The view's tag.
      * {@hide}
@@ -10901,11 +10899,21 @@
         if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) {
             return;
         }
-        if (mSendViewStateChangedAccessibilityEvent == null) {
-            mSendViewStateChangedAccessibilityEvent =
-                    new SendViewStateChangedAccessibilityEvent();
+        // If this is a live region, we should send a subtree change event
+        // from this view immediately. Otherwise, we can let it propagate up.
+        if (getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE) {
+            final AccessibilityEvent event = AccessibilityEvent.obtain();
+            event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+            event.setContentChangeTypes(changeType);
+            sendAccessibilityEventUnchecked(event);
+        } else if (mParent != null) {
+            try {
+                mParent.notifySubtreeAccessibilityStateChanged(this, this, changeType);
+            } catch (AbstractMethodError e) {
+                Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                        " does not fully implement ViewParent", e);
+            }
         }
-        mSendViewStateChangedAccessibilityEvent.runOrPost(changeType);
     }
 
     /**
@@ -20506,6 +20514,9 @@
      * @throws IllegalStateException if the drawable could not be found.
      */
     @Nullable private Drawable getAutofilledDrawable() {
+        if (mAttachInfo == null) {
+            return null;
+        }
         // Lazily load the isAutofilled drawable.
         if (mAttachInfo.mAutofilledDrawable == null) {
             Context rootContext = getRootView().getContext();
@@ -25720,79 +25731,6 @@
         }
     }
 
-    private class SendViewStateChangedAccessibilityEvent implements Runnable {
-        private int mChangeTypes = 0;
-        private boolean mPosted;
-        private boolean mPostedWithDelay;
-        private long mLastEventTimeMillis;
-
-        @Override
-        public void run() {
-            mPosted = false;
-            mPostedWithDelay = false;
-            mLastEventTimeMillis = SystemClock.uptimeMillis();
-            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-                final AccessibilityEvent event = AccessibilityEvent.obtain();
-                event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
-                event.setContentChangeTypes(mChangeTypes);
-                sendAccessibilityEventUnchecked(event);
-            }
-            mChangeTypes = 0;
-        }
-
-        public void runOrPost(int changeType) {
-            mChangeTypes |= changeType;
-
-            // If this is a live region or the child of a live region, collect
-            // all events from this frame and send them on the next frame.
-            if (inLiveRegion()) {
-                // If we're already posted with a delay, remove that.
-                if (mPostedWithDelay) {
-                    removeCallbacks(this);
-                    mPostedWithDelay = false;
-                }
-                // Only post if we're not already posted.
-                if (!mPosted) {
-                    post(this);
-                    mPosted = true;
-                }
-                return;
-            }
-
-            if (mPosted) {
-                return;
-            }
-
-            final long timeSinceLastMillis = SystemClock.uptimeMillis() - mLastEventTimeMillis;
-            final long minEventIntevalMillis =
-                    ViewConfiguration.getSendRecurringAccessibilityEventsInterval();
-            if (timeSinceLastMillis >= minEventIntevalMillis) {
-                removeCallbacks(this);
-                run();
-            } else {
-                postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
-                mPostedWithDelay = true;
-            }
-        }
-    }
-
-    private boolean inLiveRegion() {
-        if (getAccessibilityLiveRegion() != View.ACCESSIBILITY_LIVE_REGION_NONE) {
-            return true;
-        }
-
-        ViewParent parent = getParent();
-        while (parent instanceof View) {
-            if (((View) parent).getAccessibilityLiveRegion()
-                    != View.ACCESSIBILITY_LIVE_REGION_NONE) {
-                return true;
-            }
-            parent = parent.getParent();
-        }
-
-        return false;
-    }
-
     /**
      * Dump all private flags in readable format, useful for documentation and
      * sanity checking.
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 50593f2..54187d3 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3535,7 +3535,8 @@
         // If this is a live region, we should send a subtree change event
         // from this view. Otherwise, we can let it propagate up.
         if (getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE) {
-            notifyViewAccessibilityStateChangedIfNeeded(changeType);
+            notifyViewAccessibilityStateChangedIfNeeded(
+                    AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
         } else if (mParent != null) {
             try {
                 mParent.notifySubtreeAccessibilityStateChanged(this, source, changeType);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 511a279..28ded55 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2401,6 +2401,9 @@
     }
 
     private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
+        if (mView == null) {
+            return;
+        }
         Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");
         try {
             mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index e4d4e7b..0973d0a 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -334,7 +334,7 @@
      */
     ViewTreeObserver(Context context) {
         sIllegalOnDrawModificationIsFatal =
-                context.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.N_MR1;
+                context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O;
     }
 
     /**
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 030c78b..dc53c22 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -589,6 +589,13 @@
          * Notifies window manager that {@link #isKeyguardTrustedLw} has changed.
          */
         void notifyKeyguardTrustedChanged();
+
+        /**
+         * Notifies the window manager that screen is being turned off.
+         *
+         * @param listener callback to call when display can be turned off
+         */
+        void screenTurningOff(ScreenOffListener listener);
     }
 
     public interface PointerEventListener {
@@ -1267,6 +1274,15 @@
     public void screenTurnedOn();
 
     /**
+     * Called when the display would like to be turned off. This gives policy a chance to do some
+     * things before the display power state is actually changed to off.
+     *
+     * @param screenOffListener Must be called to tell that the display power state can actually be
+     *                          changed now after policy has done its work.
+     */
+    public void screenTurningOff(ScreenOffListener screenOffListener);
+
+    /**
      * Called when the device has turned the screen off.
      */
     public void screenTurnedOff();
@@ -1276,6 +1292,13 @@
     }
 
     /**
+     * See {@link #screenTurnedOff}
+     */
+    public interface ScreenOffListener {
+        void onScreenOff();
+    }
+
+    /**
      * Return whether the default display is on and not blocked by a black surface.
      */
     public boolean isScreenOn();
@@ -1661,4 +1684,16 @@
     public void onConfigurationChanged();
 
     public boolean shouldRotateSeamlessly(int oldRotation, int newRotation);
+
+    /**
+     * Called when System UI has been started.
+     */
+    void onSystemUiStarted();
+
+    /**
+     * Checks whether the policy is ready for dismissing the boot animation and completing the boot.
+     *
+     * @return true if ready; false otherwise.
+     */
+    boolean canDismissBootAnimation();
 }
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 8a13c0c..330aae9 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -21,6 +21,8 @@
 import android.text.TextUtils;
 import android.util.Pools.SynchronizedPool;
 
+import com.android.internal.util.BitUtils;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -618,8 +620,7 @@
     public static final int TYPE_WINDOW_CONTENT_CHANGED = 0x00000800;
 
     /**
-     * Represents the event of scrolling a view. This event type is generally not sent directly.
-     * @see View#onScrollChanged(int, int, int, int)
+     * Represents the event of scrolling a view.
      */
     public static final int TYPE_VIEW_SCROLLED = 0x00001000;
 
@@ -852,6 +853,22 @@
         return mContentChangeTypes;
     }
 
+    private static String contentChangeTypesToString(int types) {
+        return BitUtils.flagsToString(types, AccessibilityEvent::singleContentChangeTypeToString);
+    }
+
+    private static String singleContentChangeTypeToString(int type) {
+        switch (type) {
+            case CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION: {
+                return "CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION";
+            }
+            case CONTENT_CHANGE_TYPE_SUBTREE: return "CONTENT_CHANGE_TYPE_SUBTREE";
+            case CONTENT_CHANGE_TYPE_TEXT: return "CONTENT_CHANGE_TYPE_TEXT";
+            case CONTENT_CHANGE_TYPE_UNDEFINED: return "CONTENT_CHANGE_TYPE_UNDEFINED";
+            default: return Integer.toHexString(type);
+        }
+    }
+
     /**
      * Sets the bit mask of node tree changes signaled by an
      * {@link #TYPE_WINDOW_CONTENT_CHANGED} event.
@@ -1187,7 +1204,8 @@
         builder.append(super.toString());
         if (DEBUG) {
             builder.append("\n");
-            builder.append("; ContentChangeTypes: ").append(mContentChangeTypes);
+            builder.append("; ContentChangeTypes: ").append(
+                    contentChangeTypesToString(mContentChangeTypes));
             builder.append("; sourceWindowId: ").append(mSourceWindowId);
             if (mSourceNode != null) {
                 builder.append("; mSourceNodeId: ").append(mSourceNode.getSourceNodeId());
@@ -1240,183 +1258,13 @@
         while (eventType != 0) {
             final int eventTypeFlag = 1 << Integer.numberOfTrailingZeros(eventType);
             eventType &= ~eventTypeFlag;
-            switch (eventTypeFlag) {
-                case TYPE_VIEW_CLICKED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_CLICKED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_LONG_CLICKED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_LONG_CLICKED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_SELECTED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_SELECTED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_FOCUSED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_FOCUSED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_TEXT_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_TEXT_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_WINDOW_STATE_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_WINDOW_STATE_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_HOVER_ENTER: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_HOVER_ENTER");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_HOVER_EXIT: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_HOVER_EXIT");
-                    eventTypeCount++;
-                } break;
-                case TYPE_NOTIFICATION_STATE_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_NOTIFICATION_STATE_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_TOUCH_EXPLORATION_GESTURE_START: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_TOUCH_EXPLORATION_GESTURE_START");
-                    eventTypeCount++;
-                } break;
-                case TYPE_TOUCH_EXPLORATION_GESTURE_END: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_TOUCH_EXPLORATION_GESTURE_END");
-                    eventTypeCount++;
-                } break;
-                case TYPE_WINDOW_CONTENT_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_WINDOW_CONTENT_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_TEXT_SELECTION_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_TEXT_SELECTION_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_SCROLLED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_SCROLLED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_ANNOUNCEMENT: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_ANNOUNCEMENT");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_ACCESSIBILITY_FOCUSED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY");
-                    eventTypeCount++;
-                } break;
-                case TYPE_GESTURE_DETECTION_START: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_GESTURE_DETECTION_START");
-                    eventTypeCount++;
-                } break;
-                case TYPE_GESTURE_DETECTION_END: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_GESTURE_DETECTION_END");
-                    eventTypeCount++;
-                } break;
-                case TYPE_TOUCH_INTERACTION_START: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_TOUCH_INTERACTION_START");
-                    eventTypeCount++;
-                } break;
-                case TYPE_TOUCH_INTERACTION_END: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_TOUCH_INTERACTION_END");
-                    eventTypeCount++;
-                } break;
-                case TYPE_WINDOWS_CHANGED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_WINDOWS_CHANGED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_VIEW_CONTEXT_CLICKED: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_VIEW_CONTEXT_CLICKED");
-                    eventTypeCount++;
-                } break;
-                case TYPE_ASSIST_READING_CONTEXT: {
-                    if (eventTypeCount > 0) {
-                        builder.append(", ");
-                    }
-                    builder.append("TYPE_ASSIST_READING_CONTEXT");
-                    eventTypeCount++;
-                } break;
+
+            if (eventTypeCount > 0) {
+                builder.append(", ");
             }
+            builder.append(singleEventTypeToString(eventTypeFlag));
+
+            eventTypeCount++;
         }
         if (eventTypeCount > 1) {
             builder.insert(0, '[');
@@ -1425,6 +1273,43 @@
         return builder.toString();
     }
 
+    private static String singleEventTypeToString(int eventType) {
+        switch (eventType) {
+            case TYPE_VIEW_CLICKED: return "TYPE_VIEW_CLICKED";
+            case TYPE_VIEW_LONG_CLICKED: return "TYPE_VIEW_LONG_CLICKED";
+            case TYPE_VIEW_SELECTED: return "TYPE_VIEW_SELECTED";
+            case TYPE_VIEW_FOCUSED: return "TYPE_VIEW_FOCUSED";
+            case TYPE_VIEW_TEXT_CHANGED: return "TYPE_VIEW_TEXT_CHANGED";
+            case TYPE_WINDOW_STATE_CHANGED: return "TYPE_WINDOW_STATE_CHANGED";
+            case TYPE_VIEW_HOVER_ENTER: return "TYPE_VIEW_HOVER_ENTER";
+            case TYPE_VIEW_HOVER_EXIT: return "TYPE_VIEW_HOVER_EXIT";
+            case TYPE_NOTIFICATION_STATE_CHANGED: return "TYPE_NOTIFICATION_STATE_CHANGED";
+            case TYPE_TOUCH_EXPLORATION_GESTURE_START: {
+                return "TYPE_TOUCH_EXPLORATION_GESTURE_START";
+            }
+            case TYPE_TOUCH_EXPLORATION_GESTURE_END: return "TYPE_TOUCH_EXPLORATION_GESTURE_END";
+            case TYPE_WINDOW_CONTENT_CHANGED: return "TYPE_WINDOW_CONTENT_CHANGED";
+            case TYPE_VIEW_TEXT_SELECTION_CHANGED: return "TYPE_VIEW_TEXT_SELECTION_CHANGED";
+            case TYPE_VIEW_SCROLLED: return "TYPE_VIEW_SCROLLED";
+            case TYPE_ANNOUNCEMENT: return "TYPE_ANNOUNCEMENT";
+            case TYPE_VIEW_ACCESSIBILITY_FOCUSED: return "TYPE_VIEW_ACCESSIBILITY_FOCUSED";
+            case TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
+                return "TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED";
+            }
+            case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: {
+                return "TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY";
+            }
+            case TYPE_GESTURE_DETECTION_START: return "TYPE_GESTURE_DETECTION_START";
+            case TYPE_GESTURE_DETECTION_END: return "TYPE_GESTURE_DETECTION_END";
+            case TYPE_TOUCH_INTERACTION_START: return "TYPE_TOUCH_INTERACTION_START";
+            case TYPE_TOUCH_INTERACTION_END: return "TYPE_TOUCH_INTERACTION_END";
+            case TYPE_WINDOWS_CHANGED: return "TYPE_WINDOWS_CHANGED";
+            case TYPE_VIEW_CONTEXT_CLICKED: return "TYPE_VIEW_CONTEXT_CLICKED";
+            case TYPE_ASSIST_READING_CONTEXT: return "TYPE_ASSIST_READING_CONTEXT";
+            default: return Integer.toHexString(eventType);
+        }
+    }
+
     /**
      * @see Parcelable.Creator
      */
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 5148d92..3bf8d27 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -16,6 +16,9 @@
 
 package android.view.accessibility;
 
+import static com.android.internal.util.BitUtils.bitAt;
+import static com.android.internal.util.BitUtils.isBitSet;
+
 import static java.util.Collections.EMPTY_LIST;
 
 import android.accessibilityservice.AccessibilityService;
@@ -41,10 +44,12 @@
 import android.view.View;
 
 import com.android.internal.R;
+import com.android.internal.util.CollectionUtils;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -636,7 +641,6 @@
      * Bits that provide the id of a virtual descendant of a view.
      */
     private static final long VIRTUAL_DESCENDANT_ID_MASK = 0xffffffff00000000L;
-
     /**
      * Bit shift of {@link #VIRTUAL_DESCENDANT_ID_MASK} to get to the id for a
      * virtual descendant of a view. Such a descendant does not exist in the view
@@ -692,6 +696,8 @@
     private static final SynchronizedPool<AccessibilityNodeInfo> sPool =
             new SynchronizedPool<>(MAX_POOL_SIZE);
 
+    private static final AccessibilityNodeInfo DEFAULT = new AccessibilityNodeInfo();
+
     private boolean mSealed;
 
     // Data.
@@ -1068,11 +1074,7 @@
      * Gets the actions that can be performed on the node.
      */
     public List<AccessibilityAction> getActionList() {
-        if (mActions == null) {
-            return Collections.emptyList();
-        }
-
-        return mActions;
+        return CollectionUtils.emptyIfNull(mActions);
     }
 
     /**
@@ -3050,127 +3052,227 @@
      */
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeInt(isSealed() ? 1 : 0);
-        parcel.writeLong(mSourceNodeId);
-        parcel.writeInt(mWindowId);
-        parcel.writeLong(mParentNodeId);
-        parcel.writeLong(mLabelForId);
-        parcel.writeLong(mLabeledById);
-        parcel.writeLong(mTraversalBefore);
-        parcel.writeLong(mTraversalAfter);
-
-        parcel.writeInt(mConnectionId);
-
-        final LongArray childIds = mChildNodeIds;
-        if (childIds == null) {
-            parcel.writeInt(0);
-        } else {
-            final int childIdsSize = childIds.size();
-            parcel.writeInt(childIdsSize);
-            for (int i = 0; i < childIdsSize; i++) {
-                parcel.writeLong(childIds.get(i));
-            }
+        // Write bit set of indices of fields with values differing from default
+        long nonDefaultFields = 0;
+        int fieldIndex = 0; // index of the current field
+        if (isSealed() != DEFAULT.isSealed()) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mSourceNodeId != DEFAULT.mSourceNodeId) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mWindowId != DEFAULT.mWindowId) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mParentNodeId != DEFAULT.mParentNodeId) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mLabelForId != DEFAULT.mLabelForId) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mLabeledById != DEFAULT.mLabeledById) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mTraversalBefore != DEFAULT.mTraversalBefore) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mTraversalAfter != DEFAULT.mTraversalAfter) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mConnectionId != DEFAULT.mConnectionId) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mChildNodeIds, DEFAULT.mChildNodeIds)) {
+            nonDefaultFields |= bitAt(fieldIndex);
         }
+        fieldIndex++;
+        if (!Objects.equals(mBoundsInParent, DEFAULT.mBoundsInParent)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mBoundsInScreen, DEFAULT.mBoundsInScreen)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mActions, DEFAULT.mActions)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mMaxTextLength != DEFAULT.mMaxTextLength) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mMovementGranularities != DEFAULT.mMovementGranularities) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (mBooleanProperties != DEFAULT.mBooleanProperties) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mPackageName, DEFAULT.mPackageName)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mClassName, DEFAULT.mClassName)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mText, DEFAULT.mText)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mHintText, DEFAULT.mHintText)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mError, DEFAULT.mError)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mContentDescription, DEFAULT.mContentDescription)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mViewIdResourceName, DEFAULT.mViewIdResourceName)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (mTextSelectionStart != DEFAULT.mTextSelectionStart) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (mTextSelectionEnd != DEFAULT.mTextSelectionEnd) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (mInputType != DEFAULT.mInputType) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mLiveRegion != DEFAULT.mLiveRegion) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (mDrawingOrderInParent != DEFAULT.mDrawingOrderInParent) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mExtraDataKeys, DEFAULT.mExtraDataKeys)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mExtras, DEFAULT.mExtras)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mRangeInfo, DEFAULT.mRangeInfo)) nonDefaultFields |= bitAt(fieldIndex);
+        fieldIndex++;
+        if (!Objects.equals(mCollectionInfo, DEFAULT.mCollectionInfo)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+        if (!Objects.equals(mCollectionItemInfo, DEFAULT.mCollectionItemInfo)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        int totalFields = fieldIndex;
+        parcel.writeLong(nonDefaultFields);
 
-        parcel.writeInt(mBoundsInParent.top);
-        parcel.writeInt(mBoundsInParent.bottom);
-        parcel.writeInt(mBoundsInParent.left);
-        parcel.writeInt(mBoundsInParent.right);
+        fieldIndex = 0;
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(isSealed() ? 1 : 0);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mSourceNodeId);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mWindowId);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mParentNodeId);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mLabelForId);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mLabeledById);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mTraversalBefore);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeLong(mTraversalAfter);
 
-        parcel.writeInt(mBoundsInScreen.top);
-        parcel.writeInt(mBoundsInScreen.bottom);
-        parcel.writeInt(mBoundsInScreen.left);
-        parcel.writeInt(mBoundsInScreen.right);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mConnectionId);
 
-        if (mActions != null && !mActions.isEmpty()) {
-            final int actionCount = mActions.size();
-
-            int nonLegacyActionCount = 0;
-            int defaultLegacyStandardActions = 0;
-            for (int i = 0; i < actionCount; i++) {
-                AccessibilityAction action = mActions.get(i);
-                if (isDefaultLegacyStandardAction(action)) {
-                    defaultLegacyStandardActions |= action.getId();
-                } else {
-                    nonLegacyActionCount++;
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            final LongArray childIds = mChildNodeIds;
+            if (childIds == null) {
+                parcel.writeInt(0);
+            } else {
+                final int childIdsSize = childIds.size();
+                parcel.writeInt(childIdsSize);
+                for (int i = 0; i < childIdsSize; i++) {
+                    parcel.writeLong(childIds.get(i));
                 }
             }
-            parcel.writeInt(defaultLegacyStandardActions);
-            parcel.writeInt(nonLegacyActionCount);
+        }
 
-            for (int i = 0; i < actionCount; i++) {
-                AccessibilityAction action = mActions.get(i);
-                if (!isDefaultLegacyStandardAction(action)) {
-                    parcel.writeInt(action.getId());
-                    parcel.writeCharSequence(action.getLabel());
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            parcel.writeInt(mBoundsInParent.top);
+            parcel.writeInt(mBoundsInParent.bottom);
+            parcel.writeInt(mBoundsInParent.left);
+            parcel.writeInt(mBoundsInParent.right);
+        }
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            parcel.writeInt(mBoundsInScreen.top);
+            parcel.writeInt(mBoundsInScreen.bottom);
+            parcel.writeInt(mBoundsInScreen.left);
+            parcel.writeInt(mBoundsInScreen.right);
+        }
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            if (mActions != null && !mActions.isEmpty()) {
+                final int actionCount = mActions.size();
+
+                int nonLegacyActionCount = 0;
+                int defaultLegacyStandardActions = 0;
+                for (int i = 0; i < actionCount; i++) {
+                    AccessibilityAction action = mActions.get(i);
+                    if (isDefaultLegacyStandardAction(action)) {
+                        defaultLegacyStandardActions |= action.getId();
+                    } else {
+                        nonLegacyActionCount++;
+                    }
                 }
+                parcel.writeInt(defaultLegacyStandardActions);
+                parcel.writeInt(nonLegacyActionCount);
+
+                for (int i = 0; i < actionCount; i++) {
+                    AccessibilityAction action = mActions.get(i);
+                    if (!isDefaultLegacyStandardAction(action)) {
+                        parcel.writeInt(action.getId());
+                        parcel.writeCharSequence(action.getLabel());
+                    }
+                }
+            } else {
+                parcel.writeInt(0);
+                parcel.writeInt(0);
             }
-        } else {
-            parcel.writeInt(0);
-            parcel.writeInt(0);
         }
 
-        parcel.writeInt(mMaxTextLength);
-        parcel.writeInt(mMovementGranularities);
-        parcel.writeInt(mBooleanProperties);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mMaxTextLength);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mMovementGranularities);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mBooleanProperties);
 
-        parcel.writeCharSequence(mPackageName);
-        parcel.writeCharSequence(mClassName);
-        parcel.writeCharSequence(mText);
-        parcel.writeCharSequence(mHintText);
-        parcel.writeCharSequence(mError);
-        parcel.writeCharSequence(mContentDescription);
-        parcel.writeString(mViewIdResourceName);
-
-        parcel.writeInt(mTextSelectionStart);
-        parcel.writeInt(mTextSelectionEnd);
-        parcel.writeInt(mInputType);
-        parcel.writeInt(mLiveRegion);
-        parcel.writeInt(mDrawingOrderInParent);
-        if (mExtraDataKeys != null) {
-            parcel.writeInt(1);
-            parcel.writeStringList(mExtraDataKeys);
-        } else {
-            parcel.writeInt(0);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mPackageName);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mClassName);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mText);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mHintText);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mError);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            parcel.writeCharSequence(mContentDescription);
         }
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeString(mViewIdResourceName);
 
-        if (mExtras != null) {
-            parcel.writeInt(1);
-            parcel.writeBundle(mExtras);
-        } else {
-            parcel.writeInt(0);
-        }
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mTextSelectionStart);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mTextSelectionEnd);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mInputType);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mLiveRegion);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeInt(mDrawingOrderInParent);
 
-        if (mRangeInfo != null) {
-            parcel.writeInt(1);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeStringList(mExtraDataKeys);
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeBundle(mExtras);
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
             parcel.writeInt(mRangeInfo.getType());
             parcel.writeFloat(mRangeInfo.getMin());
             parcel.writeFloat(mRangeInfo.getMax());
             parcel.writeFloat(mRangeInfo.getCurrent());
-        } else {
-            parcel.writeInt(0);
         }
 
-        if (mCollectionInfo != null) {
-            parcel.writeInt(1);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
             parcel.writeInt(mCollectionInfo.getRowCount());
             parcel.writeInt(mCollectionInfo.getColumnCount());
             parcel.writeInt(mCollectionInfo.isHierarchical() ? 1 : 0);
             parcel.writeInt(mCollectionInfo.getSelectionMode());
-        } else {
-            parcel.writeInt(0);
         }
 
-        if (mCollectionItemInfo != null) {
-            parcel.writeInt(1);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
             parcel.writeInt(mCollectionItemInfo.getRowIndex());
             parcel.writeInt(mCollectionItemInfo.getRowSpan());
             parcel.writeInt(mCollectionItemInfo.getColumnIndex());
             parcel.writeInt(mCollectionItemInfo.getColumnSpan());
             parcel.writeInt(mCollectionItemInfo.isHeading() ? 1 : 0);
             parcel.writeInt(mCollectionItemInfo.isSelected() ? 1 : 0);
-        } else {
-            parcel.writeInt(0);
+        }
+
+        if (DEBUG) {
+            fieldIndex--;
+            if (totalFields != fieldIndex) {
+                throw new IllegalStateException("Number of fields mismatch: " + totalFields
+                        + " vs " + fieldIndex);
+            }
         }
 
         // Since instances of this class are fetched via synchronous i.e. blocking
@@ -3203,12 +3305,12 @@
         mContentDescription = other.mContentDescription;
         mViewIdResourceName = other.mViewIdResourceName;
 
+        if (mActions != null) mActions.clear();
         final ArrayList<AccessibilityAction> otherActions = other.mActions;
         if (otherActions != null && otherActions.size() > 0) {
             if (mActions == null) {
                 mActions = new ArrayList(otherActions);
             } else {
-                mActions.clear();
                 mActions.addAll(other.mActions);
             }
         }
@@ -3217,12 +3319,13 @@
         mMaxTextLength = other.mMaxTextLength;
         mMovementGranularities = other.mMovementGranularities;
 
+
+        if (mChildNodeIds != null) mChildNodeIds.clear();
         final LongArray otherChildNodeIds = other.mChildNodeIds;
         if (otherChildNodeIds != null && otherChildNodeIds.size() > 0) {
             if (mChildNodeIds == null) {
                 mChildNodeIds = otherChildNodeIds.clone();
             } else {
-                mChildNodeIds.clear();
                 mChildNodeIds.addAll(otherChildNodeIds);
             }
         }
@@ -3232,17 +3335,18 @@
         mInputType = other.mInputType;
         mLiveRegion = other.mLiveRegion;
         mDrawingOrderInParent = other.mDrawingOrderInParent;
+
         mExtraDataKeys = other.mExtraDataKeys;
 
-        if (other.mExtras != null) {
-            mExtras = new Bundle(other.mExtras);
-        } else {
-            mExtras = null;
-        }
+        mExtras = other.mExtras != null ? new Bundle(other.mExtras) : null;
+
+        if (mRangeInfo != null) mRangeInfo.recycle();
         mRangeInfo = (other.mRangeInfo != null)
                 ? RangeInfo.obtain(other.mRangeInfo) : null;
+        if (mCollectionInfo != null) mCollectionInfo.recycle();
         mCollectionInfo = (other.mCollectionInfo != null)
                 ? CollectionInfo.obtain(other.mCollectionInfo) : null;
+        if (mCollectionItemInfo != null) mCollectionItemInfo.recycle();
         mCollectionItemInfo =  (other.mCollectionItemInfo != null)
                 ? CollectionItemInfo.obtain(other.mCollectionItemInfo) : null;
     }
@@ -3253,103 +3357,117 @@
      * @param parcel A parcel containing the state of a {@link AccessibilityNodeInfo}.
      */
     private void initFromParcel(Parcel parcel) {
-        final boolean sealed = (parcel.readInt()  == 1);
-        mSourceNodeId = parcel.readLong();
-        mWindowId = parcel.readInt();
-        mParentNodeId = parcel.readLong();
-        mLabelForId = parcel.readLong();
-        mLabeledById = parcel.readLong();
-        mTraversalBefore = parcel.readLong();
-        mTraversalAfter = parcel.readLong();
+        // Bit mask of non-default-valued field indices
+        long nonDefaultFields = parcel.readLong();
+        int fieldIndex = 0;
+        final boolean sealed = isBitSet(nonDefaultFields, fieldIndex++)
+                ? (parcel.readInt() == 1)
+                : DEFAULT.mSealed;
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mSourceNodeId = parcel.readLong();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mWindowId = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mParentNodeId = parcel.readLong();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mLabelForId = parcel.readLong();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mLabeledById = parcel.readLong();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mTraversalBefore = parcel.readLong();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mTraversalAfter = parcel.readLong();
 
-        mConnectionId = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mConnectionId = parcel.readInt();
 
-        final int childrenSize = parcel.readInt();
-        if (childrenSize <= 0) {
-            mChildNodeIds = null;
-        } else {
-            mChildNodeIds = new LongArray(childrenSize);
-            for (int i = 0; i < childrenSize; i++) {
-                final long childId = parcel.readLong();
-                mChildNodeIds.add(childId);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            final int childrenSize = parcel.readInt();
+            if (childrenSize <= 0) {
+                mChildNodeIds = null;
+            } else {
+                mChildNodeIds = new LongArray(childrenSize);
+                for (int i = 0; i < childrenSize; i++) {
+                    final long childId = parcel.readLong();
+                    mChildNodeIds.add(childId);
+                }
             }
         }
 
-        mBoundsInParent.top = parcel.readInt();
-        mBoundsInParent.bottom = parcel.readInt();
-        mBoundsInParent.left = parcel.readInt();
-        mBoundsInParent.right = parcel.readInt();
-
-        mBoundsInScreen.top = parcel.readInt();
-        mBoundsInScreen.bottom = parcel.readInt();
-        mBoundsInScreen.left = parcel.readInt();
-        mBoundsInScreen.right = parcel.readInt();
-
-        final int legacyStandardActions = parcel.readInt();
-        addLegacyStandardActions(legacyStandardActions);
-        final int nonLegacyActionCount = parcel.readInt();
-        for (int i = 0; i < nonLegacyActionCount; i++) {
-            final AccessibilityAction action = new AccessibilityAction(
-                    parcel.readInt(), parcel.readCharSequence());
-            addActionUnchecked(action);
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            mBoundsInParent.top = parcel.readInt();
+            mBoundsInParent.bottom = parcel.readInt();
+            mBoundsInParent.left = parcel.readInt();
+            mBoundsInParent.right = parcel.readInt();
         }
 
-        mMaxTextLength = parcel.readInt();
-        mMovementGranularities = parcel.readInt();
-        mBooleanProperties = parcel.readInt();
-
-        mPackageName = parcel.readCharSequence();
-        mClassName = parcel.readCharSequence();
-        mText = parcel.readCharSequence();
-        mHintText = parcel.readCharSequence();
-        mError = parcel.readCharSequence();
-        mContentDescription = parcel.readCharSequence();
-        mViewIdResourceName = parcel.readString();
-
-        mTextSelectionStart = parcel.readInt();
-        mTextSelectionEnd = parcel.readInt();
-
-        mInputType = parcel.readInt();
-        mLiveRegion = parcel.readInt();
-        mDrawingOrderInParent = parcel.readInt();
-
-        if (parcel.readInt() == 1) {
-            mExtraDataKeys = parcel.createStringArrayList();
-        } else {
-            mExtraDataKeys = null;
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            mBoundsInScreen.top = parcel.readInt();
+            mBoundsInScreen.bottom = parcel.readInt();
+            mBoundsInScreen.left = parcel.readInt();
+            mBoundsInScreen.right = parcel.readInt();
         }
 
-        if (parcel.readInt() == 1) {
-            mExtras = parcel.readBundle();
-        } else {
-            mExtras = null;
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            final int legacyStandardActions = parcel.readInt();
+            addLegacyStandardActions(legacyStandardActions);
+            final int nonLegacyActionCount = parcel.readInt();
+            for (int i = 0; i < nonLegacyActionCount; i++) {
+                final AccessibilityAction action = new AccessibilityAction(
+                        parcel.readInt(), parcel.readCharSequence());
+                addActionUnchecked(action);
+            }
         }
 
-        if (parcel.readInt() == 1) {
-            mRangeInfo = RangeInfo.obtain(
-                    parcel.readInt(),
-                    parcel.readFloat(),
-                    parcel.readFloat(),
-                    parcel.readFloat());
-        }
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mMaxTextLength = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mMovementGranularities = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mBooleanProperties = parcel.readInt();
 
-        if (parcel.readInt() == 1) {
-            mCollectionInfo = CollectionInfo.obtain(
-                    parcel.readInt(),
-                    parcel.readInt(),
-                    parcel.readInt() == 1,
-                    parcel.readInt());
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mPackageName = parcel.readCharSequence();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mClassName = parcel.readCharSequence();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mText = parcel.readCharSequence();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mHintText = parcel.readCharSequence();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mError = parcel.readCharSequence();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            mContentDescription = parcel.readCharSequence();
         }
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mViewIdResourceName = parcel.readString();
 
-        if (parcel.readInt() == 1) {
-            mCollectionItemInfo = CollectionItemInfo.obtain(
-                    parcel.readInt(),
-                    parcel.readInt(),
-                    parcel.readInt(),
-                    parcel.readInt(),
-                    parcel.readInt() == 1,
-                    parcel.readInt() == 1);
-        }
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mTextSelectionStart = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mTextSelectionEnd = parcel.readInt();
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mInputType = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mLiveRegion = parcel.readInt();
+        if (isBitSet(nonDefaultFields, fieldIndex++)) mDrawingOrderInParent = parcel.readInt();
+
+        mExtraDataKeys = isBitSet(nonDefaultFields, fieldIndex++)
+                ? parcel.createStringArrayList()
+                : null;
+
+        mExtras = isBitSet(nonDefaultFields, fieldIndex++)
+                ? parcel.readBundle()
+                : null;
+
+        if (mRangeInfo != null) mRangeInfo.recycle();
+        mRangeInfo = isBitSet(nonDefaultFields, fieldIndex++)
+                ? RangeInfo.obtain(
+                        parcel.readInt(),
+                        parcel.readFloat(),
+                        parcel.readFloat(),
+                        parcel.readFloat())
+                : null;
+
+        if (mCollectionInfo != null) mCollectionInfo.recycle();
+        mCollectionInfo = isBitSet(nonDefaultFields, fieldIndex++)
+                ? CollectionInfo.obtain(
+                        parcel.readInt(),
+                        parcel.readInt(),
+                        parcel.readInt() == 1,
+                        parcel.readInt())
+                : null;
+
+        if (mCollectionItemInfo != null) mCollectionItemInfo.recycle();
+        mCollectionItemInfo = isBitSet(nonDefaultFields, fieldIndex++)
+                ? CollectionItemInfo.obtain(
+                        parcel.readInt(),
+                        parcel.readInt(),
+                        parcel.readInt(),
+                        parcel.readInt(),
+                        parcel.readInt() == 1,
+                        parcel.readInt() == 1)
+                : null;
 
         mSealed = sealed;
     }
@@ -3358,50 +3476,7 @@
      * Clears the state of this instance.
      */
     private void clear() {
-        mSealed = false;
-        mSourceNodeId = UNDEFINED_NODE_ID;
-        mParentNodeId = UNDEFINED_NODE_ID;
-        mLabelForId = UNDEFINED_NODE_ID;
-        mLabeledById = UNDEFINED_NODE_ID;
-        mTraversalBefore = UNDEFINED_NODE_ID;
-        mTraversalAfter = UNDEFINED_NODE_ID;
-        mWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
-        mConnectionId = UNDEFINED_CONNECTION_ID;
-        mMaxTextLength = -1;
-        mMovementGranularities = 0;
-        if (mChildNodeIds != null) {
-            mChildNodeIds.clear();
-        }
-        mBoundsInParent.set(0, 0, 0, 0);
-        mBoundsInScreen.set(0, 0, 0, 0);
-        mBooleanProperties = 0;
-        mDrawingOrderInParent = 0;
-        mExtraDataKeys = null;
-        mPackageName = null;
-        mClassName = null;
-        mText = null;
-        mHintText = null;
-        mError = null;
-        mContentDescription = null;
-        mViewIdResourceName = null;
-        removeAllActions();
-        mTextSelectionStart = UNDEFINED_SELECTION_INDEX;
-        mTextSelectionEnd = UNDEFINED_SELECTION_INDEX;
-        mInputType = InputType.TYPE_NULL;
-        mLiveRegion = View.ACCESSIBILITY_LIVE_REGION_NONE;
-        mExtras = null;
-        if (mRangeInfo != null) {
-            mRangeInfo.recycle();
-            mRangeInfo = null;
-        }
-        if (mCollectionInfo != null) {
-            mCollectionInfo.recycle();
-            mCollectionInfo = null;
-        }
-        if (mCollectionItemInfo != null) {
-            mCollectionItemInfo.recycle();
-            mCollectionItemInfo = null;
-        }
+        init(DEFAULT);
     }
 
     private static boolean isDefaultLegacyStandardAction(AccessibilityAction action) {
diff --git a/core/java/android/webkit/UserPackage.java b/core/java/android/webkit/UserPackage.java
index f53b5d6..8920089 100644
--- a/core/java/android/webkit/UserPackage.java
+++ b/core/java/android/webkit/UserPackage.java
@@ -83,8 +83,7 @@
      * supported by the current framework version.
      */
     public static boolean hasCorrectTargetSdkVersion(PackageInfo packageInfo) {
-        // TODO(gsennton) use Build.VERSION_CODES.O when that has been updated.
-        return packageInfo.applicationInfo.targetSdkVersion > Build.VERSION_CODES.N_MR1;
+        return packageInfo.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.O;
     }
 
     public UserInfo getUserInfo() {
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index be0967f..cfd1445 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -16,7 +16,7 @@
 
 package android.widget;
 
-import static android.os.Build.VERSION_CODES.N_MR1;
+import static android.os.Build.VERSION_CODES.O;
 
 import android.annotation.Nullable;
 import android.content.Context;
@@ -302,7 +302,7 @@
         getTempCalendarForTime(timeInMillis);
 
         final int targetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
-        if (targetSdkVersion > N_MR1) {
+        if (targetSdkVersion >= O) {
             if (mTempCalendar.before(mMinDate) || mTempCalendar.after(mMaxDate)) {
                 throw new IllegalArgumentException("timeInMillis must be between the values of "
                         + "getMinDate() and getMaxDate()");
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index d456989..7bdd6da 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -737,7 +737,6 @@
         mInputText.setFilters(new InputFilter[] {
             new InputTextFilter()
         });
-        mInputText.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
 
         mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
         mInputText.setImeOptions(EditorInfo.IME_ACTION_DONE);
@@ -771,12 +770,6 @@
         if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
             setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
         }
-
-        // Should be focusable by default, as the text view whose visibility changes is focusable
-        if (getFocusable() == View.FOCUSABLE_AUTO) {
-            setFocusable(View.FOCUSABLE);
-            setFocusableInTouchMode(true);
-        }
     }
 
     @Override
@@ -863,7 +856,7 @@
         switch (action) {
             case MotionEvent.ACTION_DOWN: {
                 removeAllCallbacks();
-                hideSoftInput();
+                mInputText.setVisibility(View.INVISIBLE);
                 mLastDownOrMoveEventY = mLastDownEventY = event.getY();
                 mLastDownEventTime = event.getEventTime();
                 mIgnoreMoveEvents = false;
@@ -890,9 +883,11 @@
                     mFlingScroller.forceFinished(true);
                     mAdjustScroller.forceFinished(true);
                 } else if (mLastDownEventY < mTopSelectionDividerTop) {
+                    hideSoftInput();
                     postChangeCurrentByOneFromLongPress(
                             false, ViewConfiguration.getLongPressTimeout());
                 } else if (mLastDownEventY > mBottomSelectionDividerBottom) {
+                    hideSoftInput();
                     postChangeCurrentByOneFromLongPress(
                             true, ViewConfiguration.getLongPressTimeout());
                 } else {
@@ -1125,7 +1120,6 @@
     @Override
     public void scrollBy(int x, int y) {
         int[] selectorIndices = mSelectorIndices;
-        int startScrollOffset = mCurrentScrollOffset;
         if (!mWrapSelectorWheel && y > 0
                 && selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] <= mMinValue) {
             mCurrentScrollOffset = mInitialScrollOffset;
@@ -1153,9 +1147,6 @@
                 mCurrentScrollOffset = mInitialScrollOffset;
             }
         }
-        if (startScrollOffset != mCurrentScrollOffset) {
-            onScrollChanged(0, mCurrentScrollOffset, 0, startScrollOffset);
-        }
     }
 
     @Override
@@ -1744,10 +1735,7 @@
         }
         int previous = mValue;
         mValue = current;
-        // If we're flinging, we'll update the text view at the end when it becomes visible
-        if (mScrollState != OnScrollListener.SCROLL_STATE_FLING) {
-            updateInputTextView();
-        }
+        updateInputTextView();
         if (notifyChange) {
             notifyChange(previous, current);
         }
@@ -1764,7 +1752,7 @@
      */
      private void changeValueByOne(boolean increment) {
         if (mHasSelectorWheel) {
-            hideSoftInput();
+            mInputText.setVisibility(View.INVISIBLE);
             if (!moveToFinalScrollerPosition(mFlingScroller)) {
                 moveToFinalScrollerPosition(mAdjustScroller);
             }
@@ -1811,8 +1799,9 @@
      */
     private void onScrollerFinished(Scroller scroller) {
         if (scroller == mFlingScroller) {
-            ensureScrollWheelAdjusted();
-            updateInputTextView();
+            if (!ensureScrollWheelAdjusted()) {
+                updateInputTextView();
+            }
             onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
         } else {
             if (mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
@@ -1948,25 +1937,9 @@
          */
         String text = (mDisplayedValues == null) ? formatNumber(mValue)
                 : mDisplayedValues[mValue - mMinValue];
-        if (!TextUtils.isEmpty(text)) {
-            CharSequence beforeText = mInputText.getText();
-            if (!text.equals(beforeText.toString())) {
-                mInputText.setText(text);
-                if (mAccessibilityNodeProvider != null) {
-                    AccessibilityEvent event = AccessibilityEvent.obtain(
-                            AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
-                    mInputText.onInitializeAccessibilityEvent(event);
-                    mInputText.onPopulateAccessibilityEvent(event);
-                    event.setFromIndex(0);
-                    event.setRemovedCount(beforeText.length());
-                    event.setAddedCount(text.length());
-                    event.setBeforeText(beforeText);
-                    event.setSource(NumberPicker.this,
-                            AccessibilityNodeProviderImpl.VIRTUAL_VIEW_ID_INPUT);
-                    requestSendAccessibilityEvent(NumberPicker.this, event);
-                }
-                return true;
-            }
+        if (!TextUtils.isEmpty(text) && !text.equals(mInputText.getText().toString())) {
+            mInputText.setText(text);
+            return true;
         }
 
         return false;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 77f27d9..3a4d008 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1653,6 +1653,7 @@
                                 ? (val.data == 0 ? NOT_FOCUSABLE : FOCUSABLE)
                                 : val.data;
                     }
+                    break;
 
                 case com.android.internal.R.styleable.View_clickable:
                     clickable = a.getBoolean(attr, clickable);
@@ -11227,8 +11228,10 @@
                 return true;
 
             case DragEvent.ACTION_DRAG_LOCATION:
-                final int offset = getOffsetForPosition(event.getX(), event.getY());
-                Selection.setSelection((Spannable) mText, offset);
+                if (mText instanceof Spannable) {
+                    final int offset = getOffsetForPosition(event.getX(), event.getY());
+                    Selection.setSelection((Spannable) mText, offset);
+                }
                 return true;
 
             case DragEvent.ACTION_DROP:
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index 13ebe5c..d807120 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -449,6 +449,11 @@
         public void handleShow(IBinder windowToken) {
             if (localLOGV) Log.v(TAG, "HANDLE SHOW: " + this + " mView=" + mView
                     + " mNextView=" + mNextView);
+            // If a cancel/hide is pending - no need to show - at this point
+            // the window token is already invalid and no need to do any work.
+            if (mHandler.hasMessages(CANCEL) || mHandler.hasMessages(HIDE)) {
+                return;
+            }
             if (mView != mNextView) {
                 // remove the old view if necessary
                 handleHide();
@@ -483,8 +488,16 @@
                     mWM.removeView(mView);
                 }
                 if (localLOGV) Log.v(TAG, "ADD! " + mView + " in " + this);
-                mWM.addView(mView, mParams);
-                trySendAccessibilityEvent();
+                // Since the notification manager service cancels the token right
+                // after it notifies us to cancel the toast there is an inherent
+                // race and we may attempt to add a window after the token has been
+                // invalidated. Let us hedge against that.
+                try {
+                    mWM.addView(mView, mParams);
+                    trySendAccessibilityEvent();
+                } catch (WindowManager.BadTokenException e) {
+                    /* ignore */
+                }
             }
         }
 
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 342cff6..f28e862 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -116,7 +116,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    private static final int VERSION = 157 + (USE_OLD_HISTORY ? 1000 : 0);
+    private static final int VERSION = 158 + (USE_OLD_HISTORY ? 1000 : 0);
 
     // Maximum number of items we will record in the history.
     private static final int MAX_HISTORY_ITEMS = 2000;
@@ -169,7 +169,6 @@
 
     public interface PlatformIdleStateCallback {
         public String getPlatformLowPowerStats();
-        public String getSubsystemLowPowerStats();
     }
 
     private final PlatformIdleStateCallback mPlatformIdleStateCallback;
@@ -968,14 +967,15 @@
         }
     }
 
+    @VisibleForTesting
     public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs {
         final TimeBase mTimeBase;
-        long[] mCounts;
-        long[] mLoadedCounts;
-        long[] mUnpluggedCounts;
-        long[] mPluggedCounts;
+        public long[] mCounts;
+        public long[] mLoadedCounts;
+        public long[] mUnpluggedCounts;
+        public long[] mPluggedCounts;
 
-        LongSamplingCounterArray(TimeBase timeBase, Parcel in) {
+        private LongSamplingCounterArray(TimeBase timeBase, Parcel in) {
             mTimeBase = timeBase;
             mPluggedCounts = in.createLongArray();
             mCounts = copyArray(mPluggedCounts, mCounts);
@@ -984,12 +984,12 @@
             timeBase.add(this);
         }
 
-        LongSamplingCounterArray(TimeBase timeBase) {
+        public LongSamplingCounterArray(TimeBase timeBase) {
             mTimeBase = timeBase;
             timeBase.add(this);
         }
 
-        public void writeToParcel(Parcel out) {
+        private void writeToParcel(Parcel out) {
             out.writeLongArray(mCounts);
             out.writeLongArray(mLoadedCounts);
             out.writeLongArray(mUnpluggedCounts);
@@ -1025,7 +1025,7 @@
                     + " mPluggedCounts=" + Arrays.toString(mPluggedCounts));
         }
 
-        void addCountLocked(long[] counts) {
+        public void addCountLocked(long[] counts) {
             if (counts == null) {
                 return;
             }
@@ -1040,7 +1040,7 @@
         /**
          * Clear state of this counter.
          */
-        void reset(boolean detachIfReset) {
+        public void reset(boolean detachIfReset) {
             fillArray(mCounts, 0);
             fillArray(mLoadedCounts, 0);
             fillArray(mPluggedCounts, 0);
@@ -1050,21 +1050,60 @@
             }
         }
 
-        void detach() {
+        public void detach() {
             mTimeBase.remove(this);
         }
 
-        void writeSummaryFromParcelLocked(Parcel out) {
+        private void writeSummaryToParcelLocked(Parcel out) {
             out.writeLongArray(mCounts);
         }
 
-        void readSummaryFromParcelLocked(Parcel in) {
+        private void readSummaryFromParcelLocked(Parcel in) {
             mCounts = in.createLongArray();
             mLoadedCounts = copyArray(mCounts, mLoadedCounts);
             mUnpluggedCounts = copyArray(mCounts, mUnpluggedCounts);
             mPluggedCounts = copyArray(mCounts, mPluggedCounts);
         }
 
+        public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) {
+            if (counterArray != null) {
+                out.writeInt(1);
+                counterArray.writeToParcel(out);
+            } else {
+                out.writeInt(0);
+            }
+        }
+
+        public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) {
+            if (in.readInt() != 0) {
+                return new LongSamplingCounterArray(timeBase, in);
+            } else {
+                return null;
+            }
+        }
+
+        public static void writeSummaryToParcelLocked(Parcel out,
+                LongSamplingCounterArray counterArray) {
+            if (counterArray != null) {
+                out.writeInt(1);
+                counterArray.writeSummaryToParcelLocked(out);
+            } else {
+                out.writeInt(0);
+            }
+        }
+
+        public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in,
+                TimeBase timeBase) {
+            if (in.readInt() != 0) {
+                final LongSamplingCounterArray counterArray
+                        = new LongSamplingCounterArray(timeBase);
+                counterArray.readSummaryFromParcelLocked(in);
+                return counterArray;
+            } else {
+                return null;
+            }
+        }
+
         private void fillArray(long[] a, long val) {
             if (a != null) {
                 Arrays.fill(a, val);
@@ -2843,12 +2882,6 @@
                         mPlatformIdleStateCallback.getPlatformLowPowerStats();
                 if (DEBUG) Slog.i(TAG, "WRITE PlatformIdleState:" +
                         mCurHistoryStepDetails.statPlatformIdleState);
-
-                mCurHistoryStepDetails.statSubsystemPowerState =
-                        mPlatformIdleStateCallback.getSubsystemLowPowerStats();
-                if (DEBUG) Slog.i(TAG, "WRITE SubsystemPowerState:" +
-                        mCurHistoryStepDetails.statSubsystemPowerState);
-
             }
             computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails);
             if (includeStepDetails != 0) {
@@ -3434,8 +3467,8 @@
         boolean batteryStatusChanged = mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime);
 
         if (batteryStatusChanged) {
-            for (int i=0; i<mUidStats.size(); i++) {
-                mUidStats.valueAt(i).updateBgTimeBase(uptime, realtime);
+            for (int i = 0; i < mUidStats.size(); i++) {
+                mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptime, realtime);
             }
         }
 
@@ -3449,6 +3482,9 @@
             }
             updateCpuTimeLocked();
             mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime);
+            for (int i = 0; i < mUidStats.size(); i++) {
+                mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptime, realtime);
+            }
         }
     }
 
@@ -5548,6 +5584,8 @@
         /** TimeBase for when uid is in background and device is on battery. */
         @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
         public final TimeBase mOnBatteryBackgroundTimeBase;
+        @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+        public final TimeBase mOnBatteryScreenOffBackgroundTimeBase;
 
         boolean mWifiRunning;
         StopwatchTimer mWifiRunningTimer;
@@ -5570,6 +5608,8 @@
         StopwatchTimer mFlashlightTurnedOnTimer;
         StopwatchTimer mCameraTurnedOnTimer;
         StopwatchTimer mForegroundActivityTimer;
+        /** Total time spent by the uid holding any partial wakelocks. */
+        DualTimer mAggregatedPartialWakelockTimer;
         DualTimer mBluetoothScanTimer;
         Counter mBluetoothScanResultCounter;
 
@@ -5671,6 +5711,10 @@
             mOnBatteryBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000,
                     mBsi.mClocks.elapsedRealtime() * 1000);
 
+            mOnBatteryScreenOffBackgroundTimeBase = new TimeBase();
+            mOnBatteryScreenOffBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000,
+                    mBsi.mClocks.elapsedRealtime() * 1000);
+
             mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
             mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
 
@@ -5741,6 +5785,11 @@
         }
 
         @Override
+        public Timer getAggregatedPartialWakelockTimer() {
+            return mAggregatedPartialWakelockTimer;
+        }
+
+        @Override
         public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
             return mWakelockStats.getMap();
         }
@@ -6029,6 +6078,15 @@
             return mForegroundActivityTimer;
         }
 
+        public DualTimer createAggregatedPartialWakelockTimerLocked() {
+            if (mAggregatedPartialWakelockTimer == null) {
+                mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this,
+                        AGGREGATED_WAKE_TYPE_PARTIAL, null,
+                        mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase);
+            }
+            return mAggregatedPartialWakelockTimer;
+        }
+
         public DualTimer createBluetoothScanTimerLocked() {
             if (mBluetoothScanTimer == null) {
                 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON,
@@ -6471,6 +6529,7 @@
             active |= !resetTimerIfNotNull(mFlashlightTurnedOnTimer, false);
             active |= !resetTimerIfNotNull(mCameraTurnedOnTimer, false);
             active |= !resetTimerIfNotNull(mForegroundActivityTimer, false);
+            active |= !resetTimerIfNotNull(mAggregatedPartialWakelockTimer, false);
             active |= !resetTimerIfNotNull(mBluetoothScanTimer, false);
             if (mBluetoothScanResultCounter != null) {
                 mBluetoothScanResultCounter.reset(false);
@@ -6623,6 +6682,8 @@
 
             mOnBatteryBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000,
                     mBsi.mClocks.uptimeMillis() * 1000);
+            mOnBatteryScreenOffBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000,
+                    mBsi.mClocks.uptimeMillis() * 1000);
 
             if (!active) {
                 if (mWifiRunningTimer != null) {
@@ -6662,6 +6723,10 @@
                     mForegroundActivityTimer.detach();
                     mForegroundActivityTimer = null;
                 }
+                if (mAggregatedPartialWakelockTimer != null) {
+                    mAggregatedPartialWakelockTimer.detach();
+                    mAggregatedPartialWakelockTimer = null;
+                }
                 if (mBluetoothScanTimer != null) {
                     mBluetoothScanTimer.detach();
                     mBluetoothScanTimer = null;
@@ -6727,6 +6792,7 @@
 
         void writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs) {
             mOnBatteryBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs);
+            mOnBatteryScreenOffBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs);
 
             final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
             int NW = wakeStats.size();
@@ -6841,6 +6907,12 @@
             } else {
                 out.writeInt(0);
             }
+            if (mAggregatedPartialWakelockTimer != null) {
+                out.writeInt(1);
+                mAggregatedPartialWakelockTimer.writeToParcel(out, elapsedRealtimeUs);
+            } else {
+                out.writeInt(0);
+            }
             if (mBluetoothScanTimer != null) {
                 out.writeInt(1);
                 mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs);
@@ -6934,18 +7006,8 @@
                 out.writeInt(0);
             }
 
-            if (mCpuFreqTimeMs != null) {
-                out.writeInt(1);
-                mCpuFreqTimeMs.writeToParcel(out);
-            } else {
-                out.writeInt(0);
-            }
-            if (mScreenOffCpuFreqTimeMs != null) {
-                out.writeInt(1);
-                mScreenOffCpuFreqTimeMs.writeToParcel(out);
-            } else {
-                out.writeInt(0);
-            }
+            LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs);
+            LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs);
 
             if (mMobileRadioApWakeupCount != null) {
                 out.writeInt(1);
@@ -6964,6 +7026,7 @@
 
         void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
             mOnBatteryBackgroundTimeBase.readFromParcel(in);
+            mOnBatteryScreenOffBackgroundTimeBase.readFromParcel(in);
 
             int numWakelocks = in.readInt();
             mWakelockStats.clear();
@@ -7090,6 +7153,14 @@
                 mForegroundActivityTimer = null;
             }
             if (in.readInt() != 0) {
+                mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this,
+                        AGGREGATED_WAKE_TYPE_PARTIAL, null,
+                        mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase,
+                        in);
+            } else {
+                mAggregatedPartialWakelockTimer = null;
+            }
+            if (in.readInt() != 0) {
                 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON,
                         mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase,
                         mOnBatteryBackgroundTimeBase, in);
@@ -7194,17 +7265,9 @@
                 mCpuClusterSpeed = null;
             }
 
-            if (in.readInt() != 0) {
-                mCpuFreqTimeMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in);
-            } else {
-                mCpuFreqTimeMs = null;
-            }
-            if (in.readInt() != 0) {
-                mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray(
-                        mBsi.mOnBatteryScreenOffTimeBase, in);
-            } else {
-                mScreenOffCpuFreqTimeMs = null;
-            }
+            mCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(in, mBsi.mOnBatteryTimeBase);
+            mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(
+                    in, mBsi.mOnBatteryScreenOffTimeBase);
 
             if (in.readInt() != 0) {
                 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
@@ -8209,15 +8272,25 @@
                 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs);
             }
 
-            updateBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000);
+            updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000);
+            updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000);
         }
 
-        public boolean updateBgTimeBase(long uptimeUs, long realtimeUs) {
+        /** Whether to consider Uid to be in the background for background timebase purposes. */
+        public boolean isInBackground() {
             // Note that PROCESS_STATE_CACHED and ActivityManager.PROCESS_STATE_NONEXISTENT is
             // also considered to be 'background' for our purposes, because it's not foreground.
-            boolean isBgAndUnplugged = mBsi.mOnBatteryTimeBase.isRunning()
-                    && mProcessState >= PROCESS_STATE_BACKGROUND;
-            return mOnBatteryBackgroundTimeBase.setRunning(isBgAndUnplugged, uptimeUs, realtimeUs);
+            return mProcessState >= PROCESS_STATE_BACKGROUND;
+        }
+
+        public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) {
+            boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground();
+            return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs);
+        }
+
+        public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) {
+            boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground();
+            return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs);
         }
 
         public SparseArray<? extends Pid> getPidStats() {
@@ -8348,10 +8421,13 @@
             if (wl != null) {
                 wl.getStopwatchTimer(type).startRunningLocked(elapsedRealtimeMs);
             }
-            if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
-                Pid p = getPidStatsLocked(pid);
-                if (p.mWakeNesting++ == 0) {
-                    p.mWakeStartMs = elapsedRealtimeMs;
+            if (type == WAKE_TYPE_PARTIAL) {
+                createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs);
+                if (pid >= 0) {
+                    Pid p = getPidStatsLocked(pid);
+                    if (p.mWakeNesting++ == 0) {
+                        p.mWakeStartMs = elapsedRealtimeMs;
+                    }
                 }
             }
         }
@@ -8361,12 +8437,17 @@
             if (wl != null) {
                 wl.getStopwatchTimer(type).stopRunningLocked(elapsedRealtimeMs);
             }
-            if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
-                Pid p = mPids.get(pid);
-                if (p != null && p.mWakeNesting > 0) {
-                    if (p.mWakeNesting-- == 1) {
-                        p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
-                        p.mWakeStartMs = 0;
+            if (type == WAKE_TYPE_PARTIAL) {
+                if (mAggregatedPartialWakelockTimer != null) {
+                    mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs);
+                }
+                if (pid >= 0) {
+                    Pid p = mPids.get(pid);
+                    if (p != null && p.mWakeNesting > 0) {
+                        if (p.mWakeNesting-- == 1) {
+                            p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
+                            p.mWakeStartMs = 0;
+                        }
                     }
                 }
             }
@@ -11250,6 +11331,7 @@
             mUidStats.put(uid, u);
 
             u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in);
+            u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in);
 
             u.mWifiRunning = false;
             if (in.readInt() != 0) {
@@ -11290,6 +11372,9 @@
                 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
             }
             if (in.readInt() != 0) {
+                u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in);
+            }
+            if (in.readInt() != 0) {
                 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in);
             }
             if (in.readInt() != 0) {
@@ -11362,19 +11447,10 @@
                 u.mCpuClusterSpeed = null;
             }
 
-            if (in.readInt() != 0) {
-                u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase);
-                u.mCpuFreqTimeMs.readSummaryFromParcelLocked(in);
-            } else {
-                u.mCpuFreqTimeMs = null;
-            }
-            if (in.readInt() != 0) {
-                u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray(
-                        mOnBatteryScreenOffTimeBase);
-                u.mScreenOffCpuFreqTimeMs.readSummaryFromParcelLocked(in);
-            } else {
-                u.mScreenOffCpuFreqTimeMs = null;
-            }
+            u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked(
+                    in, mOnBatteryTimeBase);
+            u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked(
+                    in, mOnBatteryScreenOffTimeBase);
 
             if (in.readInt() != 0) {
                 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase);
@@ -11635,6 +11711,7 @@
             Uid u = mUidStats.valueAt(iu);
 
             u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
+            u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
 
             if (u.mWifiRunningTimer != null) {
                 out.writeInt(1);
@@ -11698,6 +11775,12 @@
             } else {
                 out.writeInt(0);
             }
+            if (u.mAggregatedPartialWakelockTimer != null) {
+                out.writeInt(1);
+                u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+            } else {
+                out.writeInt(0);
+            }
             if (u.mBluetoothScanTimer != null) {
                 out.writeInt(1);
                 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
@@ -11772,18 +11855,8 @@
                 out.writeInt(0);
             }
 
-            if (u.mCpuFreqTimeMs != null) {
-                out.writeInt(1);
-                u.mCpuFreqTimeMs.writeSummaryFromParcelLocked(out);
-            } else {
-                out.writeInt(0);
-            }
-            if (u.mScreenOffCpuFreqTimeMs != null) {
-                out.writeInt(1);
-                u.mScreenOffCpuFreqTimeMs.writeSummaryFromParcelLocked(out);
-            } else {
-                out.writeInt(0);
-            }
+            LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs);
+            LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs);
 
             if (u.mMobileRadioApWakeupCount != null) {
                 out.writeInt(1);
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index a9bec41..2013ac0 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -762,14 +762,6 @@
     public static void applyInvokeWithSystemProperty(Arguments args) {
         if (args.invokeWith == null && args.niceName != null) {
             String property = "wrap." + args.niceName;
-            if (property.length() > 31) {
-                // Properties with a trailing "." are illegal.
-                if (property.charAt(30) != '.') {
-                    property = property.substring(0, 31);
-                } else {
-                    property = property.substring(0, 30);
-                }
-            }
             args.invokeWith = SystemProperties.get(property);
             if (args.invokeWith != null && args.invokeWith.length() == 0) {
                 args.invokeWith = null;
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 1b83708..9823431 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -296,7 +296,11 @@
     @Override
     public void onDraw(Canvas c) {
         super.onDraw(c);
-        mBackgroundFallback.draw(mContentRoot, c, mWindow.mContentParent);
+
+        // When we are resizing, we need the fallback background to cover the area where we have our
+        // system bar background views as the navigation bar will be hidden during resizing.
+        mBackgroundFallback.draw(isResizing() ? this : mContentRoot, mContentRoot, c,
+                mWindow.mContentParent);
     }
 
     @Override
diff --git a/core/java/com/android/internal/util/BitUtils.java b/core/java/com/android/internal/util/BitUtils.java
index 1b354d0..28f12eb 100644
--- a/core/java/com/android/internal/util/BitUtils.java
+++ b/core/java/com/android/internal/util/BitUtils.java
@@ -18,12 +18,14 @@
 package com.android.internal.util;
 
 import android.annotation.Nullable;
+import android.text.TextUtils;
 
 import libcore.util.Objects;
 
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.UUID;
+import java.util.function.IntFunction;
 
 /**
  * A utility class for handling unsigned integers and unsigned arithmetics, as well as syntactic
@@ -124,4 +126,26 @@
         buffer.put(bytes);
         buffer.position(original);
     }
+
+    public static boolean isBitSet(long flags, int bitIndex) {
+        return (flags & bitAt(bitIndex)) != 0;
+    }
+
+    public static long bitAt(int bitIndex) {
+        return 1L << bitIndex;
+    }
+
+    public static String flagsToString(int flags, IntFunction<String> getFlagName) {
+        StringBuilder builder = new StringBuilder();
+        int count = 0;
+        while (flags != 0) {
+            final int flag = 1 << Integer.numberOfTrailingZeros(flags);
+            flags &= ~flag;
+            if (count > 0) builder.append(", ");
+            builder.append(getFlagName.apply(flag));
+            count++;
+        }
+        TextUtils.wrap(builder, "[", "]");
+        return builder.toString();
+    }
 }
diff --git a/core/java/com/android/internal/widget/BackgroundFallback.java b/core/java/com/android/internal/widget/BackgroundFallback.java
index 4adba4d..309f80c 100644
--- a/core/java/com/android/internal/widget/BackgroundFallback.java
+++ b/core/java/com/android/internal/widget/BackgroundFallback.java
@@ -39,14 +39,22 @@
         return mBackgroundFallback != null;
     }
 
-    public void draw(ViewGroup root, Canvas c, View content) {
+    /**
+     * Draws the fallback background.
+     *
+     * @param boundsView The view determining with which bounds the background should be drawn.
+     * @param root The view group containing the content.
+     * @param c The canvas to draw the background onto.
+     * @param content The view where the actual app content is contained in.
+     */
+    public void draw(ViewGroup boundsView, ViewGroup root, Canvas c, View content) {
         if (!hasFallback()) {
             return;
         }
 
         // Draw the fallback in the padding.
-        final int width = root.getWidth();
-        final int height = root.getHeight();
+        final int width = boundsView.getWidth();
+        final int height = boundsView.getHeight();
         int left = width;
         int top = height;
         int right = 0;
diff --git a/core/java/com/android/internal/widget/ImageFloatingTextView.java b/core/java/com/android/internal/widget/ImageFloatingTextView.java
index e86932c..6b53368 100644
--- a/core/java/com/android/internal/widget/ImageFloatingTextView.java
+++ b/core/java/com/android/internal/widget/ImageFloatingTextView.java
@@ -169,4 +169,8 @@
         }
         return false;
     }
+
+    public int getLayoutHeight() {
+        return getLayout().getHeight();
+    }
 }
diff --git a/core/java/com/android/internal/widget/MessagingLinearLayout.java b/core/java/com/android/internal/widget/MessagingLinearLayout.java
index 1104318..70473a0 100644
--- a/core/java/com/android/internal/widget/MessagingLinearLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLinearLayout.java
@@ -138,7 +138,7 @@
                 first = false;
                 boolean measuredTooSmall = false;
                 if (textChild != null) {
-                    measuredTooSmall = childHeight < textChild.getLayout().getHeight()
+                    measuredTooSmall = childHeight < textChild.getLayoutHeight()
                             + textChild.getPaddingTop() + textChild.getPaddingBottom();
                 }
 
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index bc23b16..b0a2e11 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -277,12 +277,18 @@
     ],
 
     local_include_dirs: ["android/graphics"],
-    export_include_dirs: ["include"],
+    export_include_dirs: [
+        ".",
+        "include",
+    ],
     export_shared_lib_headers: [
         // AndroidRuntime.h depends on nativehelper/jni.h
         "libnativehelper",
 
         // our headers include libnativewindow's public headers
         "libnativewindow",
+
+        // GraphicsJNI.h includes hwui headers
+        "libhwui",
     ],
 }
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index b529e37..5f803da 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -50,27 +50,27 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
-static void Shader_safeUnref(JNIEnv* env, jobject o, jlong shaderHandle) {
-    SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle);
+static void Shader_safeUnref(SkShader* shader) {
     SkSafeUnref(shader);
 }
 
+static jlong Shader_getNativeFinalizer(JNIEnv*, jobject) {
+    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Shader_safeUnref));
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
 static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jobject jbitmap,
         jint tileModeX, jint tileModeY) {
     const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
-    sk_sp<SkImage> image;
+    SkBitmap bitmap;
     if (jbitmap) {
         // Only pass a valid SkBitmap object to the constructor if the Bitmap exists. Otherwise,
         // we'll pass an empty SkBitmap to avoid crashing/excepting for compatibility.
-        image = android::bitmap::toBitmap(env, jbitmap).makeImage(nullptr);
+        android::bitmap::toBitmap(env, jbitmap).getSkBitmapForShaders(&bitmap);
     }
 
-    if (!image.get()) {
-        SkBitmap bitmap;
-        image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
-    }
+    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
     sk_sp<SkShader> baseShader = image->makeShader(
             (SkShader::TileMode)tileModeX, (SkShader::TileMode)tileModeY);
 
@@ -287,7 +287,7 @@
 };
 
 static const JNINativeMethod gShaderMethods[] = {
-    { "nativeSafeUnref",   "(J)V",    (void*)Shader_safeUnref },
+    { "nativeGetFinalizer",   "()J",    (void*)Shader_getNativeFinalizer },
 };
 
 static const JNINativeMethod gBitmapShaderMethods[] = {
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 5aea2b7..cd7aae7 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -119,11 +119,7 @@
     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
     if (parcel != NULL) {
         const status_t err = parcel->setDataSize(size);
-        //STOPSHIP: check for BADFLO is for a temporary debug using wtf. Remove once bug resolved.
-        if (err == UNKNOWN_ERROR + 0xBADF10) {
-            jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
-                         "Attempt to resize (size = %d) Parcel would corrupt object memory", size);
-        } else if (err != NO_ERROR) {
+        if (err != NO_ERROR) {
             signalExceptionForError(env, clazz, err);
         }
         return parcel->getOpenAshmemSize();
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index e1c0a21..aa1893c 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -570,18 +570,6 @@
     mObserver->decStrong(nullptr);
 }
 
-static jboolean android_view_ThreadedRenderer_supportsOpenGL(JNIEnv* env, jobject clazz) {
-    char prop[PROPERTY_VALUE_MAX];
-    if (property_get("ro.kernel.qemu", prop, NULL) == 0) {
-        // not in the emulator
-        return JNI_TRUE;
-    }
-    // In the emulator this property will be set > 0 when OpenGL ES 2.0 is
-    // enabled, 0 otherwise. On old emulator versions it will be undefined.
-    property_get("qemu.gles", prop, "0");
-    return atoi(prop) > 0 ? JNI_TRUE : JNI_FALSE;
-}
-
 static void android_view_ThreadedRenderer_rotateProcessStatsBuffer(JNIEnv* env, jobject clazz) {
     RenderProxy::rotateProcessStatsBuffer();
 }
@@ -898,7 +886,6 @@
 const char* const kClassPathName = "android/view/ThreadedRenderer";
 
 static const JNINativeMethod gMethods[] = {
-    { "nSupportsOpenGL", "()Z", (void*) android_view_ThreadedRenderer_supportsOpenGL },
     { "nRotateProcessStatsBuffer", "()V", (void*) android_view_ThreadedRenderer_rotateProcessStatsBuffer },
     { "nSetProcessStatsBuffer", "(I)V", (void*) android_view_ThreadedRenderer_setProcessStatsBuffer },
     { "nGetRenderThreadTid", "(J)I", (void*) android_view_ThreadedRenderer_getRenderThreadTid },
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 6000fb5..d73e7dd 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -27,6 +27,7 @@
 #include <fcntl.h>
 #include <grp.h>
 #include <inttypes.h>
+#include <malloc.h>
 #include <mntent.h>
 #include <paths.h>
 #include <signal.h>
@@ -519,6 +520,9 @@
     // The child process.
     gMallocLeakZygoteChild = 1;
 
+    // Set the jemalloc decay time to 1.
+    mallopt(M_DECAY_TIME, 1);
+
     // Clean up any descriptors which must be closed immediately
     DetachDescriptors(env, fdsToClose);
 
diff --git a/core/res/res/anim/lock_screen_behind_enter.xml b/core/res/res/anim/lock_screen_behind_enter.xml
index c96e280..c1d26e3 100644
--- a/core/res/res/anim/lock_screen_behind_enter.xml
+++ b/core/res/res/anim/lock_screen_behind_enter.xml
@@ -17,8 +17,7 @@
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:detachWallpaper="true"
-        android:shareInterpolator="false"
-        android:startOffset="100">
+        android:shareInterpolator="false">
 
     <translate android:fromYDelta="110%p" android:toYDelta="0"
             android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
diff --git a/core/res/res/anim/lock_screen_behind_enter_fade_in.xml b/core/res/res/anim/lock_screen_behind_enter_fade_in.xml
index 94e40a8..e9475f5 100644
--- a/core/res/res/anim/lock_screen_behind_enter_fade_in.xml
+++ b/core/res/res/anim/lock_screen_behind_enter_fade_in.xml
@@ -22,6 +22,5 @@
     android:interpolator="@interpolator/linear"
     android:fromAlpha="0" android:toAlpha="1"
     android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-    android:duration="250"
-    android:startOffset="100">
+    android:duration="250">
 </alpha>
\ No newline at end of file
diff --git a/core/res/res/anim/lock_screen_behind_enter_wallpaper.xml b/core/res/res/anim/lock_screen_behind_enter_wallpaper.xml
index 660b662..50156fb 100644
--- a/core/res/res/anim/lock_screen_behind_enter_wallpaper.xml
+++ b/core/res/res/anim/lock_screen_behind_enter_wallpaper.xml
@@ -16,12 +16,12 @@
   -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-    android:detachWallpaper="true" android:shareInterpolator="false" android:startOffset="100">
+    android:detachWallpaper="true" android:shareInterpolator="false" >
     <alpha
         android:fromAlpha="0.0" android:toAlpha="1.0"
         android:fillEnabled="true" android:fillBefore="true"
         android:interpolator="@interpolator/decelerate_quint"
-        android:duration="400"/>
+        android:duration="300"/>
 
     <translate android:fromYDelta="11%p" android:toYDelta="0"
         android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
diff --git a/core/res/res/anim/lock_screen_wallpaper_exit.xml b/core/res/res/anim/lock_screen_wallpaper_exit.xml
index 49d0327..ba8741a 100644
--- a/core/res/res/anim/lock_screen_wallpaper_exit.xml
+++ b/core/res/res/anim/lock_screen_wallpaper_exit.xml
@@ -16,12 +16,12 @@
   -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:shareInterpolator="false" android:startOffset="100">
+        android:shareInterpolator="false">
     <alpha
         android:fromAlpha="1.0" android:toAlpha="0.0"
         android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
         android:interpolator="@interpolator/fast_out_linear_in"
-        android:duration="150"/>
+        android:duration="200"/>
 
     <!-- Empty animation so the animation has same duration as lock_screen_behind_enter animation
          -->
diff --git a/core/res/res/layout-land/time_picker_material.xml b/core/res/res/layout-land/time_picker_material.xml
index 8b95f9f..863efef 100644
--- a/core/res/res/layout-land/time_picker_material.xml
+++ b/core/res/res/layout-land/time_picker_material.xml
@@ -20,11 +20,10 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content">
 
-    <LinearLayout
+    <RelativeLayout
         android:id="@+id/time_header"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
-        android:orientation="vertical"
         android:gravity="center"
         android:paddingStart="?attr/dialogPreferredPadding"
         android:paddingEnd="?attr/dialogPreferredPadding">
@@ -112,7 +111,7 @@
                 android:includeFontPadding="false"
                 android:button="@null" />
         </RadioGroup>
-    </LinearLayout>
+    </RelativeLayout>
 
     <TextView
         android:visibility="gone"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index da414fa7..5e52de9 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Opdaterings"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Netwerkstatus"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Netwerkwaarskuwings"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Netwerk is beskikbaar"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN-status"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Toesteladministrasie"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Opletberigte"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Vingerafdrukuittelling is bereik. Probeer weer."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Vingerafdrukhandeling is gekanselleer."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Te veel pogings. Probeer later weer."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Probeer weer."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 12afe97..3cde574 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"ዝማኔዎች"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"የአውታረ መረብ ሁኔታ"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"የአውታረ መረብ ማንቂያዎች"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"አውታረ መረብ ይገኛል"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"የቪፒኤን ሁኔታ"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"የመሣሪያ አስተዳደር"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ማንቂያዎች"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"የጣት አሻራ ማብቂያ ጊዜ ደርሷል። እንደገና ይሞክሩ።"</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"የጣት አሻራ ስርዓተ ክወና ተትቷል።"</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"ከልክ በላይ ብዙ ሙከራዎች። በኋላ ላይ እንደገና ይሞክሩ።"</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"እንደገና ይሞክሩ።"</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"ጣት <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 93c0108..14cec4c 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -272,8 +272,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"التحديثات"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"حالة الشبكة"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"تنبيهات الشبكة"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"الشبكة متوفرة"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"حالة الشبكة الظاهرية الخاصة"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"إدارة الجهاز"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"التنبيهات"</string>
@@ -504,6 +503,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"تم بلوغ مهلة إدخال بصمة الإصبع. أعد المحاولة."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"تم إلغاء تشغيل بصمة الإصبع."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"تم إجراء عدد كبير من المحاولات. أعد المحاولة لاحقًا."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"أعد المحاولة."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"الإصبع <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 1afcda0..ae1d5fd 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Güncəlləmələr"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Şəbəkə statusu"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Şəbəkə siqnalları"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Şəbəkə əlçatandır"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN statusu"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Cihaz administrasiyası"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Siqnallar"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Barmaq izinin vaxtı başa çatdı. Yenidən cəhd edin."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Barmaq izi əməliyyatı ləğv edildi."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Cəhdlər çox oldu. Sonraya saxlayın."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Yenidən cəhd edin."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Barmaq <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index cdaf0c4..c7e3f49 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -263,8 +263,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Ažuriranja"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Status mreže"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Obaveštenja u vezi sa mrežom"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Mreža je dostupna"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Status VPN-a"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administriranje uređaja"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Obaveštenja"</string>
@@ -495,6 +494,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Vremensko ograničenje za otisak prsta je isteklo. Probajte ponovo."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Radnja sa otiskom prsta je otkazana."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Previše pokušaja. Probajte ponovo kasnije."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Probajte ponovo."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 24ff545..2fbbc20 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -266,8 +266,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Абнаўленні"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Стан сеткі"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Абвесткі сеткі"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Сетка даступная"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Стан VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Адміністраванне прылады"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Абвесткi"</string>
@@ -498,6 +497,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Час чакання адбіткаў пальцаў выйшаў. Паспрабуйце яшчэ раз."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Аперацыя з адбіткамі пальцаў скасавана."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Занадта шмат спроб. Паспрабуйце яшчэ раз пазней."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Паспрабуйце яшчэ раз."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index b44efce..8272e45 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Времето за изчакване за отпечатък изтече. Опитайте отново."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Операцията за отпечатък е анулирана."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Твърде много опити. Пробвайте отново по-късно."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Опитайте отново."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Пръст <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index caa00d8..edbac70 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"আঙ্গুলের ছাপ নেওয়ার সময়সীমা শেষ হযেছে৷ আবার চেষ্টা করুন৷"</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"আঙ্গুলের ছাপ অপারেশন বাতিল করা হয়েছে৷"</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"অনেকবার প্রচেষ্টা করা হয়েছে৷ পরে আবার চেষ্টা করুন৷"</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"আবার চেষ্টা করুন৷"</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"আঙ্গুল <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index df97030..8743cf8 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -263,8 +263,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Ažuriranja"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Status mreže"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Mrežna upozorenja"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Mreža je dostupna"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Status VPN-a"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administracija uređaja"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Upozorenja"</string>
@@ -495,6 +494,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Vremensko ograničenje za otisak prsta je isteklo. Pokušajte ponovo."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Radnja sa otiskom prsta je otkazana."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Previše pokušaja. Pokušajte ponovo kasnije."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Pokušajte ponovo."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 27b985a..4b8b84b 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Actualitzacions"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Estat de la xarxa"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alertes de xarxa"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Hi ha una xarxa disponible"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Estat de la VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administració del dispositiu"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertes"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"S\'ha esgotat el temps d\'espera per a l\'empremta digital. Torna-ho a provar."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"S\'ha cancel·lat l\'operació d\'empremta digital."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"S\'han produït massa intents. Torna-ho a provar més tard."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Torna-ho a provar."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Dit <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 389073f..38276ce 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -266,8 +266,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Aktualizace"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Stav sítě"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Síťová upozornění"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"K dispozici je síť"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Stav sítě VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administrace zařízení"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Upozornění"</string>
@@ -498,6 +497,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Časový limit sejmutí otisku prstu vypršel. Zkuste to znovu."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operace otisku prstu byla zrušena."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Příliš mnoho pokusů. Zkuste to později."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Zkuste to znovu."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 88b767b..ee5ba79 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Opdateringer"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Netværksstatus"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Netværksunderretninger"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Tilgængeligt netværk"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN-status"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Enhedsadministration"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Underretninger"</string>
@@ -301,7 +300,7 @@
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"observere tekst, du skriver"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Dette omfatter personlige data såsom kreditkortnumre og adgangskoder."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"administrere skærmforstørrelsen"</string>
-    <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrollér skærmens zoomniveau og position."</string>
+    <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Tjek skærmens zoomniveau og position."</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Udfør bevægelser"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Kan trykke, stryge, knibe sammen og udføre andre bevægelser."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Fingeraftryksbevægelser"</string>
@@ -408,8 +407,8 @@
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"Tillader, at appen sender kommandoer til SIM-kortet. Dette er meget farligt."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"tage billeder og optage video"</string>
     <string name="permdesc_camera" msgid="5392231870049240670">"Med denne app kan du tage billeder og optage video med kameraet når som helst."</string>
-    <string name="permlab_vibrate" msgid="7696427026057705834">"kontrollere vibration"</string>
-    <string name="permdesc_vibrate" msgid="6284989245902300945">"Tillader, at appen kan kontrollere vibratoren."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"administrere vibration"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"Tillader, at appen kan administrere vibratoren."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"ringe direkte op til telefonnumre"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"Tillader, at appen kan ringe til telefonnumre uden din indgriben. Dette kan resultere i uventede opkrævninger eller opkald. Bemærk, at appen med denne tilladelse ikke kan ringe til nødopkaldsnumre. Skadelige apps kan koste dig penge ved at foretage opkald uden din bekræftelse."</string>
     <string name="permlab_accessImsCallService" msgid="3574943847181793918">"få adgang til chat-opkaldstjeneste"</string>
@@ -472,7 +471,7 @@
     <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Tillader, at appen kan læse konfigurationen af ​​Bluetooth på tabletten samt kan oprette og acceptere forbindelser med parrede enheder."</string>
     <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"Giver appen lov til at se fjernsynets Bluetooth-konfiguration og til at oprette og acceptere forbindelser til parrede enheder."</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Tillader, at appen kan læse konfigurationen af ​​Bluetooth på telefonen samt kan oprette og acceptere forbindelser med parrede enheder."</string>
-    <string name="permlab_nfc" msgid="4423351274757876953">"kontrollere Near Field Communication"</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"administrere Near Field Communication"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"Tillader, at appen kan kommunikere med NFC-tags (Near Field Communication), -kort og -læsere."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"deaktivere din skærmlås"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Tillader, at appen kan deaktivere tastaturlåsen og anden form for tilknyttet adgangskodesikkerhed. Telefonen deaktiverer f.eks. tastaturlåsen ved indgående telefonopkald og aktiverer tastaturlåsen igen, når opkaldet er afsluttet."</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Registrering af fingeraftryk fik timeout. Prøv igen."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingeraftrykshandlingen blev annulleret."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Du har prøvet for mange gange. Prøv igen senere."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Prøv igen."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Fingeraftryk <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
@@ -558,7 +559,7 @@
     <string name="permlab_access_notification_policy" msgid="4247510821662059671">"have adgang til Forstyr ikke"</string>
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Giver appen tilladelse til at læse og skrive konfigurationen af Forstyr ikke."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Angiv regler for adgangskoder"</string>
-    <string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrollér længden samt tilladte tegn i adgangskoder og pinkoder til skærmlåsen."</string>
+    <string name="policydesc_limitPassword" msgid="2502021457917874968">"Tjek længden samt tilladte tegn i adgangskoder og pinkoder til skærmlåsen."</string>
     <string name="policylab_watchLogin" msgid="5091404125971980158">"Overvåg forsøg på oplåsning af skærm"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Overvåg antallet af forkert indtastede adgangskoder, når du låser skærmen op, og lås din tablet, eller slet alle data i den, hvis der er indtastet for mange forkerte adgangskoder."</string>
     <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Overvåg antallet af forkert indtastede adgangskoder ved oplåsning af skærmen, og lås tv\'et eller slet alle dets data, hvis der indtastes for mange forkerte adgangskoder."</string>
@@ -1293,7 +1294,7 @@
     <string name="vpn_text" msgid="1610714069627824309">"Tryk for at administrere netværket."</string>
     <string name="vpn_text_long" msgid="4907843483284977618">"Forbundet til <xliff:g id="SESSION">%s</xliff:g>. Tryk for at administrere netværket."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Opretter forbindelse til altid aktiveret VPN…"</string>
-    <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Always-on VPN er forbundet"</string>
+    <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Altid aktiveret VPN er forbundet"</string>
     <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"Forbindelsen til altid aktiveret VPN er afbrudt"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Fejl i altid aktiveret VPN"</string>
     <string name="vpn_lockdown_config" msgid="5099330695245008680">"Tryk for at konfigurere"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index d4f37b5..e4202ce 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Updates"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Netzwerkstatus"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Netzwerkwarnungen"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Netzwerk verfügbar"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN-Status"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Geräteverwaltung"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Warnmeldungen"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Zeitüberschreitung für Fingerabdruck. Versuche es erneut."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingerabdruckvorgang abgebrochen"</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Zu viele Versuche. Versuche es später erneut."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Bitte versuche es erneut."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 5400e50..a602d03 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Ενημερώσεις"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Κατάσταση δικτύου"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Ειδοποιήσεις δικτύου"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Το δίκτυο είναι διαθέσιμο"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Κατάσταση VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Διαχείριση συσκευής"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Ειδοποιήσεις"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Λήξη χρονικού ορίου μοναδικού χαρακτηριστικού. Δοκιμάστε ξανά."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Η λειτουργία μοναδικού χαρακτηριστικού ακυρώθηκε."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Πάρα πολλές προσπάθειες. Δοκιμάστε ξανά αργότερα."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Δοκιμάστε ξανά."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Δάχτυλο <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 3bd9113..60fd79d 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Updates"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Network status"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Network alerts"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Network available"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN status"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Device administration"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerts"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Fingerprint timeout reached. Try again."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingerprint operation cancelled."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Too many attempts. Try again later."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Try again."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 3bd9113..60fd79d 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Updates"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Network status"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Network alerts"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Network available"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN status"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Device administration"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerts"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Fingerprint timeout reached. Try again."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingerprint operation cancelled."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Too many attempts. Try again later."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Try again."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 3bd9113..60fd79d 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Updates"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Network status"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Network alerts"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Network available"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN status"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Device administration"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerts"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Fingerprint timeout reached. Try again."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingerprint operation cancelled."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Too many attempts. Try again later."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Try again."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index f18cf17..cc706fa 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Actualizaciones"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Estado de la red"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alertas de red"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Red disponible"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Estado de VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administración del dispositivo"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Finalizó el tiempo de espera para la huella digital. Vuelve a intentarlo."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Se canceló la operación de huella digital."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Demasiados intentos. Vuelve a intentarlo más tarde."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Vuelve a intentarlo."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
@@ -1756,7 +1757,7 @@
     <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opciones de autocompletar"</string>
     <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"Guardar para Autocompletar"</string>
     <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"El contenido no puede autocompletarse"</string>
-    <string name="autofill_picker_no_suggestions" msgid="3908514303773350735">"Sin sugerencias de Autocompletar"</string>
+    <string name="autofill_picker_no_suggestions" msgid="3908514303773350735">"No hay sugerencias de Autocompletar"</string>
     <plurals name="autofill_picker_some_suggestions" formatted="false" msgid="5506565809835815274">
       <item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> sugerencias de Autocompletar</item>
       <item quantity="one">Una sugerencia de Autocompletar</item>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 4bcb6a3..c96e4c3 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Actualizaciones"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Estado de la red"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alertas de la red"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Red disponible"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Estado de la VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administración del dispositivo"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Se ha alcanzado el tiempo de espera de la huella digital. Vuelve a intentarlo."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Se ha cancelado la operación de huella digital."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Demasiados intentos. Vuelve a intentarlo más tarde."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Vuelve a intentarlo."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index a11dcac..0a1b9bc 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Värskendused"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Võrgu olek"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Võrguteavitused"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Võrk on saadaval"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN-i olek"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Seadme haldamine"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Teatised"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Sõrmejälje riistvara taimeri ajalõpp. Proovige uuesti."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Sõrmejälje toiming tühistati."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Liiga palju katseid. Proovige hiljem uuesti."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Proovige uuesti."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Sõrm <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 0b636e9..5b598c6 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Eguneratzeak"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Sarearen egoera"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Sarearen alertak"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Sare bat erabilgarri dago"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN egoera"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Gailuen administrazioa"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Abisuak"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Hatz-marka digitalak prozesatzeko denbora-muga gainditu da. Saiatu berriro."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Hatz-markaren eragiketa bertan behera utzi da."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Saiakera gehiegi egin dituzu. Saiatu berriro geroago."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Saiatu berriro."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g> hatza"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d0ac0f7..859f514 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"مهلت زمانی ثبت اثر انگشت به پایان رسید. دوباره امتحان کنید."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"عملکرد اثر انگشت لغو شد."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"تلاش‌های زیادی انجام شده است. بعداً دوباره امتحان کنید."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"دوباره امتحان کنید."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"انگشت <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 394187c..ce14371 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Päivitykset"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Verkon tila"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Verkkoilmoitukset"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Verkko käytettävissä"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN-tila"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Laitteen järjestelmänvalvonta"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Ilmoitukset"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Sormenjälkitunnistimen toiminta aikakatkaistiin. Yritä uudelleen."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Sormenjälkitoiminto peruutettiin."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Liian monta yritystä. Yritä myöhemmin uudelleen."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Yritä uudelleen."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Sormi <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index f7ce174..a0b3667 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Le temps attribué pour lire l\'empreinte est écoulé. Veuillez essayer de nouveau."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Opération d\'empreinte numérique annulée."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Trop de tentatives. Veuillez réessayer plus tard."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Réessayer."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 38ae87f..d6204b0 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Mises à jour"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"État du réseau"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alertes réseau"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Réseau disponible"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"État du VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Gestion de l\'appareil"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertes"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Délai de détection de l\'empreinte numérique expiré. Veuillez réessayer."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Opération d\'empreinte numérique annulée."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Trop de tentatives. Veuillez réessayer plus tard."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Veuillez réessayer."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 7fef233..e4a83bf 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Actualizacións"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Estado da rede"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alertas de rede"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"A rede está dispoñible"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Estado da VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administración de dispositivos"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Esgotouse o tempo de espera da impresión dixital. Téntao de novo."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Cancelouse a operación da impresión dixital."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Demasiados intentos. Téntao de novo máis tarde."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Téntao de novo."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 1a4524e..ef09de4 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"અપડેટ્સ"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"નેટવર્ક સ્થિતિ"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"નેટવર્ક ચેતવણીઓ"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"નેટવર્ક ઉપલબ્ધ છે"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN સ્થિતિ"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"ઉપકરણ વ્યવસ્થાપન"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ચેતવણીઓ"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"ફિંગરપ્રિન્ટનો સમય બાહ્ય થયો. ફરી પ્રયાસ કરો."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"ફિંગરપ્રિન્ટ ઓપરેશન રદ કર્યું."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"ઘણા બધા પ્રયત્નો. પછીથી ફરી પ્રયાસ કરો."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"ફરી પ્રયાસ કરો."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"આંગળી <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 0330e40..611fa40 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"अपडेट"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"नेटवर्क की स्थिति"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"नेटवर्क संबंधी सूचनाएं"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"नेटवर्क उपलब्ध है"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN की स्थिति"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"डिवाइस का व्‍यवस्‍थापन"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"सूचनाएं"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"फ़िंगरप्रिंट का समय समाप्त हो गया. पुनः प्रयास करें."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"फ़िंगरप्रिंट क्रियान्वयन रोक दिया गया."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"बहुत अधिक प्रयास कर लिए गए हैं. बाद में पुन: प्रयास करें."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"पुन: प्रयास करें."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"अंगुली <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 84e9ebd..5fae34d 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -263,8 +263,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Ažuriranja"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Mrežni status"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Mrežna upozorenja"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Mreža je dostupna"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Status VPN-a"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administracija uređaja"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Upozorenja"</string>
@@ -495,6 +494,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Isteklo je vrijeme čekanja za otisak prsta. Pokušajte ponovo."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Radnja otiska prsta otkazana je."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Previše pokušaja. Pokušajte ponovo kasnije."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Pokušajte ponovo."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index b575f8d..437fac8 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Az ujjlenyomat-beolvasási műveletkor időtúllépés történt. Próbálkozzon újra."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Ujjlenyomattal kapcsolatos művelet megszakítva"</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Túl sok próbálkozás. Próbálja újra később."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Próbálkozzon újra."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g>. ujj"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index cb164cb..90ef155 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Թարմացումներ"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Ցանցի կարգավիճակ"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Ցանցային զգուշացումներ"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Ցանցը հասանելի է"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN կարգավիճակ"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Սարքի կառավարում"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Ծանուցումներ"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Մատնահետքի գրանցման ժամանակը սպառվել է: Փորձեք նորից:"</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Իսկորոշումը մատնահետքի միջոցով չեղարկվեց:"</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Չափից շատ փորձ եք կատարել: Փորձեք նորից քիչ հետո:"</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Փորձեք նորից:"</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Մատնահետք <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index f578346..4d6a98c 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Update"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Status jaringan"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Notifikasi jaringan"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Jaringan tersedia"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Status VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administrasi perangkat"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Notifikasi"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Waktu sidik jari habis. Coba lagi."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operasi sidik jari dibatalkan."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Terlalu banyak upaya. Coba lagi nanti."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Coba lagi."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 9662bff..abde513 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Uppfærslur"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Staða netkerfis"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Viðvaranir netkerfis"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Net í boði"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Staða VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Stjórnun tækis"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Tilkynningar"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tímamörk runnu út fyrir fingrafar. Reyndu aftur."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Hætt við fingrafarsaðgerð."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Of margar tilraunir. Reyndu aftur síðar."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Reyndu aftur."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Fingur <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index d47ff56..bfa43da 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Aggiornamenti"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Stato della rete"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Avvisi di rete"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Rete disponibile"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Stato della VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Amministrazione dispositivo"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Avvisi"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Timeout impronta digitale. Riprova."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operazione associata all\'impronta digitale annullata."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Troppi tentativi. Riprova più tardi."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Riprova."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 6834d6f..8fa27fc 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -266,8 +266,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"עדכונים"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"סטטוס הרשת"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"התראות רשת"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"יש רשת זמינה"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"‏סטטוס ה-VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"ניהול מכשירים"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"התראות"</string>
@@ -498,6 +497,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"חלף הזמן הקצוב לטביעת אצבע. נסה שוב."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"פעולת טביעת האצבע בוטלה."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"יותר מדי ניסיונות. נסה שוב מאוחר יותר."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"נסה שוב."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index e9c05b4..7b8316f4 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"アップデート"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"ネットワークのステータス"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"ネットワーク通知"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"ネットワークを利用できます"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN のステータス"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"端末管理"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"通知"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"指紋の読み取りがタイムアウトになりました。もう一度お試しください。"</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"指紋の操作をキャンセルしました。"</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"所定の回数以上間違えました。しばらくしてからもう一度お試しください。"</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"もう一度お試しください。"</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"指紋<xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index f92b834..54ac190 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"თითის ანაბეჭდის ლოდინის დრო ამოიწურა. სცადეთ ხელახლა."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"თითის ანაბეჭდის აღების ოპერაცია გაუქმდა."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"ძალიან ბევრი მცდელობა იყო. სცადეთ მოგვიანებით."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"ხელახლა სცადეთ"</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"თითი <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 863b78f..c44a28f 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Жаңартылған нұсқалар"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Желі күйі"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Желі дабылдары"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Желі қолжетімді"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN күйі"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Құрылғыны басқару"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Дабылдар"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Саусақ ізін күту уақыты бітті. Әрекетті қайталаңыз."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Саусақ ізі операциясынан бас тартылған."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Талпыныстар тым көп. Кейінірек қайталап көріңіз."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Әрекетті қайталаңыз."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g> саусағы"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index f595b4b..73422bd 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"បច្ចុប្បន្នភាព"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"ស្ថានភាព​បណ្តាញ"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"ការ​ជូនដំណឹង​អំពី​បណ្តាញ"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"មានបណ្តាញ"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"ស្ថានភាព VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"ការ​គ្រប់គ្រង​ឧបករណ៍"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ការ​ជូនដំណឹង"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"ការផ្តិតម្រាមដៃបានអស់ពេល។ សូមព្យាយាមម្តងទៀត។"</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"បានបោះបង់ប្រតិបត្តិការស្នាមម្រាមដៃ។"</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"ព្យាយាមចូលច្រើនពេកហើយ។ សូមព្យាយាមម្តងទៀតពេលក្រោយ។"</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"ព្យាយាមម្ដងទៀត។"</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"ម្រាមដៃ <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 43c404f..da777b6 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"ಬೆರಳಚ್ಚು ಅವಧಿ ಮೀರಿದೆ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"ಬೆರಳಚ್ಚು ಕಾರ್ಯಾಚರಣೆಯನ್ನು ರದ್ದುಮಾಡಲಾಗಿದೆ."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"ಹಲವಾರು ಪ್ರಯತ್ನಗಳು. ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"ಫಿಂಗರ್ <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 1a2f2d0..a16b766 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"지문 인식 시간이 초과되었습니다. 다시 시도하세요."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"지문 인식 작업이 취소되었습니다."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"시도 횟수가 너무 많습니다. 나중에 다시 시도하세요."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"다시 시도해 보세요."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"손가락 <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 7694ec7..2dd273b 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Жаңыртуулар"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Тармактын абалы"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Тармактын эскертүүлөрү"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Жеткиликтүү тармактар"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN абалы"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Түзмөктү администрациялоо"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Эскертүүлөр"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Манжа изин күтүү мөөнөтү бүттү. Кайра аракет кылыңыз."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Манжа изи иш-аракети жокко чыгарылды."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Аракеттер өтө көп болду. Кийинчерээк кайра аракет кылыңыз."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Кайра бир аракеттениңиз."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g> манжасы"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index d356bfb..14f9056 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"ອັບເດດ"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"ສະຖານະເຄືອຂ່າຍ"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"ແຈ້ງເຕືອນເຄືອຂ່າຍ"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"ມີເຄືອຂ່າຍທີ່ສາມາດໃຊ້ໄດ້"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"ສະຖານະ VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"ການເບິ່ງແຍງອຸປະກອນ"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ການເຕືອນ"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"ເວ​ລາ​ລາຍ​ນີ້ວ​ມື​ບໍ່​ເຂົ້າ​ເຖິງ​ໄດ້. ລອງ​ໃໝ່​ອີກ."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"ຍົກ​ເລີກ​ການ​ດຳ​ເນີນ​ການ​ລາຍ​ນີ້ວ​ມື​ແລ້ວ."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"ມີ​ຄວາມ​ພະ​ຍາ​ຍາມ​ຫຼາຍ​ຄັ້ງ​ເກີນ​ໄປ. ລອງ​ໃໝ່​ພາຍ​ຫຼັງ."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"ລອງໃໝ່ອີກຄັ້ງ."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"ນີ້ວ​ມື <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 92b564b..a044747 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -266,8 +266,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Naujiniai"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Tinklo būsena"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Tinklo įspėjimai"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Tinklas pasiekiamas"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN būsena"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Įrenginio administravimas"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Įspėjimai"</string>
@@ -498,6 +497,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Baigėsi kontrolinio kodo nustatymo skirtasis laikas. Bandykite dar kartą."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Kontrolinio kodo operacija atšaukta."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Per daug bandymų. Vėliau bandykite dar kartą."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Bandykite dar kartą."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g> pirštas"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index e5fd56b..d8df849 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -263,8 +263,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Atjauninājumi"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Tīkla statuss"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Tīkla brīdinājumi"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Tīkls ir pieejams"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN statuss"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Ierīces administrēšana"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Brīdinājumi"</string>
@@ -495,6 +494,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Pirkstu nospiedumu nolasīšanas aparatūras noildze. Mēģiniet vēlreiz."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Nospieduma darbība neizdevās."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Pārāk daudz mēģinājumu. Vēlāk mēģiniet vēlreiz."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Mēģiniet vēlreiz."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g>. pirksts"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-mcc505-mnc11/config.xml b/core/res/res/values-mcc505-mnc11/config.xml
new file mode 100644
index 0000000..6d085c1
--- /dev/null
+++ b/core/res/res/values-mcc505-mnc11/config.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!--Thresholds for LTE dbm in status bar-->
+    <integer-array translatable="false" name="config_lteDbmThresholds">
+        <item>-140</item>    <!-- SIGNAL_STRENGTH_NONE_OR_UNKNOWN -->
+        <item>-120</item>    <!-- SIGNAL_STRENGTH_POOR -->
+        <item>-115</item>    <!-- SIGNAL_STRENGTH_MODERATE -->
+        <item>-100</item>    <!-- SIGNAL_STRENGTH_GOOD -->
+        <item>-90</item>     <!-- SIGNAL_STRENGTH_GREAT -->
+        <item>-44</item>
+    </integer-array>
+</resources>
diff --git a/core/res/res/values-mcc505-mnc71/config.xml b/core/res/res/values-mcc505-mnc71/config.xml
new file mode 100644
index 0000000..6d085c1
--- /dev/null
+++ b/core/res/res/values-mcc505-mnc71/config.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!--Thresholds for LTE dbm in status bar-->
+    <integer-array translatable="false" name="config_lteDbmThresholds">
+        <item>-140</item>    <!-- SIGNAL_STRENGTH_NONE_OR_UNKNOWN -->
+        <item>-120</item>    <!-- SIGNAL_STRENGTH_POOR -->
+        <item>-115</item>    <!-- SIGNAL_STRENGTH_MODERATE -->
+        <item>-100</item>    <!-- SIGNAL_STRENGTH_GOOD -->
+        <item>-90</item>     <!-- SIGNAL_STRENGTH_GREAT -->
+        <item>-44</item>
+    </integer-array>
+</resources>
diff --git a/core/res/res/values-mcc505-mnc72/config.xml b/core/res/res/values-mcc505-mnc72/config.xml
new file mode 100644
index 0000000..6d085c1
--- /dev/null
+++ b/core/res/res/values-mcc505-mnc72/config.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!--Thresholds for LTE dbm in status bar-->
+    <integer-array translatable="false" name="config_lteDbmThresholds">
+        <item>-140</item>    <!-- SIGNAL_STRENGTH_NONE_OR_UNKNOWN -->
+        <item>-120</item>    <!-- SIGNAL_STRENGTH_POOR -->
+        <item>-115</item>    <!-- SIGNAL_STRENGTH_MODERATE -->
+        <item>-100</item>    <!-- SIGNAL_STRENGTH_GOOD -->
+        <item>-90</item>     <!-- SIGNAL_STRENGTH_GREAT -->
+        <item>-44</item>
+    </integer-array>
+</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 6c394a0..15ad6f5 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Ажурирања"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Статус на мрежа"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Известувања на мрежа"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Има достапна мрежа"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN-статус"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Управување со уред"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Предупредувања"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Се достигна времето на истекување на отпечатокот. Обидете се повторно."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Операцијата со отпечаток од прст се откажа."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Премногу обиди. Обидете се повторно подоцна."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Обидете се повторно."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 1661704..6d37c1e 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"വിരലടയാളം നൽകേണ്ട സമയം കഴിഞ്ഞു. വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"ഫിംഗർപ്രിന്റ് പ്രവർത്തനം റദ്ദാക്കി."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"നിരവധി തവണ ശ്രമിച്ചു. പിന്നീട് വീണ്ടും ശ്രമിക്കുക."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"വീണ്ടും ശ്രമിക്കൂ."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"കൈവിരൽ <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 54110c3..81fc2d1 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Шинэчлэлтүүд"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Сүлжээний төлөв"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Сүлжээний сануулга"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Сүлжээ боломжтой"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN төлөв"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Төхөөрөмжийн удирдлага"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Сануулга"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Хурууны хээ оруулах хугацаа өнгөрсөн байна. Дахин оруулна уу."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Хурууны хээний бүртгэл амжилтгүй боллоо."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Хэтэрхий олон оролдлоо.  Түр хүлээгээд дахин оролдоно уу."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Дахин оролдно уу."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Хурууны хээ <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index cf49975..34b0179 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"अद्यतने"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"नेटवर्क स्थिती"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"नेटवर्क सूचना"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"नेटवर्क उपलब्ध"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN स्थिती"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"डिव्हाइस प्रशासन"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"सूचना"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"फिंगरप्रिंट कालबाह्य झाले. पुन्हा प्रयत्न करा."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"फिंगरप्रिंट ऑपरेशन रद्द झाले."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"खूप प्रयत्न केले. नंतर पुन्हा प्रयत्न करा."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"पुन्हा प्रयत्न करा."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g> बोट"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index d05db83..4f18074 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tamat masa cap jari dicapai. Cuba lagi."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Pengendalian cap jari dibatalkan."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Terlalu banyak percubaan. Cuba sebentar lagi."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Cuba lagi."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 966a405..fe6d1dc 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"အပ်ဒိတ်များ"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"ကွန်ရက် အခြေအနေ"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"ကွန်ရက် သတိပေးချက်များ"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"ကွန်ရက်ချိတ်ဆက်မှု ရရှိနိုင်ပါသည်"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN အခြေအနေ"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"စက်ပစ္စည်း စီမံခန့်ခွဲမှု"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"သတိပေးချက်များ"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"လက်ဗွေရာအချိန်ကုန် သွားပါသည်။ ထပ်မံကြိုးစားပါ။"</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"လက်ဗွေရာ လုပ်ငန်း ဖျက်သိမ်းခဲ့၏။"</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"ကြိုးစာမှု အကြိမ်များနေ၏။ နောက်မှ ထပ်မံကြိုးစားပါ။"</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"ပြန်ကြိုးစားပါ"</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"လက်ချောင်း <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index d62497c..578c6c4 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tidsavbrudd for fingeravtrykk er nådd. Prøv på nytt."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingeravtrykk-operasjonen ble avbrutt."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"For mange forsøk. Prøve på nytt senere."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Prøv igjen."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 1f9f6ad..53dfeb7 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"औँठाछापको समय सकिएको छ। फेरि प्रयास गर्नुहोस्।"</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"औँठाछाप सञ्चालन रद्द गरियो।"</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"धेरै प्रयासहरू। केहि समय पछि पुन: प्रयास गर्नुहोला"</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"पुन: प्रयास गर्नुहोला।"</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"औंला <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index fa46eb1..77e54bc 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Updates"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Netwerkstatus"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Netwerkmeldingen"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Netwerk beschikbaar"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN-status"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Apparaatbeheer"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Meldingen"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Time-out bereikt voor vingerafdruk. Probeer het opnieuw."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Vingerafdrukbewerking geannuleerd."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Te veel pogingen. Probeer het later opnieuw."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Probeer het opnieuw."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index a46e797..8d511da 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਾ ਸਮਾਂ ਸਮਾਪਤ ਹੋ ਗਿਆ ਹੈ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"ਫਿੰਗਰ"</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"ਬਹੁਤ ਸਾਰੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ. ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"ਉਂਗਲ <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index f9104a2..3a8f7c5 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -266,8 +266,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Aktualizacje"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Stan sieci"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alerty dotyczące sieci"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Sieć dostępna"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Stan sieci VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administracja urządzeniem"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerty"</string>
@@ -498,6 +497,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Osiągnięto limit czasu odczytu linii papilarnych. Spróbuj ponownie."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Odczyt odcisku palca został anulowany."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Zbyt wiele prób. Spróbuj ponownie później."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Spróbuj ponownie."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Odcisk palca <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 56bd3b8..421a12e 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tempo máximo para captura da impressão digital atingido. Tente novamente."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operação de impressão digital cancelada."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Excesso de tentativas. Tente novamente mais tarde."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Tente novamente."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index feae0ee..463b684 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Atualizações"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Estado da rede"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alertas da rede"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Rede disponível"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Estado da VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administração do dispositivo"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Foi atingido o limite de tempo da impressão digital. Tente novamente."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operação de impressão digital cancelada."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Demasiadas tentativas. Tente novamente mais tarde."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Tente novamente."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 56bd3b8..421a12e 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tempo máximo para captura da impressão digital atingido. Tente novamente."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operação de impressão digital cancelada."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Excesso de tentativas. Tente novamente mais tarde."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Tente novamente."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 2b7f5e3..4f8f047 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -263,8 +263,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Actualizări"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Starea rețelei"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alerte privind rețeaua"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Rețea disponibilă"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Stare VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administrarea dispozitivului"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alerte"</string>
@@ -495,6 +494,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Timpul pentru amprentare a expirat. Încercați din nou."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operațiunea privind amprenta a fost anulată."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Prea multe încercări. Încercați din nou mai târziu."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Încercați din nou."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Degetul <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 48e22b0..4a0ef0c 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -266,8 +266,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Обновления"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Статус сети"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Оповещения сети"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Сеть доступна"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Статус VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Управление устройством"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Уведомления"</string>
@@ -498,6 +497,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Превышено время ожидания. Повторите попытку."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Операция с отпечатком отменена."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Слишком много попыток. Повторите позже."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Повторите попытку."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 565c09c..a738032 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"යාවත්කාලීන කිරීම්"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"ජාල තත්ත්වය"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"ජාල ඇඟවීම්"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"ජාලය ලබා ගැනීමට හැකිය"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN තත්ත්වය"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"උපාංග පරිපාලනය"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ඇඟවීම්"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"ඇඟිලි සලකුණු කාල නිමාව ළඟා විය. නැවත උත්සාහ කරන්න."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"ඇඟිලි සලකුණු මෙහෙයුම අවලංගු කරන ලදී."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"උත්සාහයන් ඉතා වැඩි ගණනකි. කරුණාකර පසුව නැවත උත්සාහ කරන්න."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"නැවත උත්සාහ කරන්න."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"ඇඟිලි <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index b151645..e942b95 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -498,6 +498,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Časový limit rozpoznania odtlačku vypršal. Skúste to znova."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operácia týkajúca sa odtlačku prsta bola zrušená"</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Príliš veľa pokusov. Skúste to znova neskôr."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Skúste to znova"</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Prst: <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index ea9192f..646eba1 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -266,8 +266,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Posodobitve"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Stanje omrežja"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Opozorila omrežja"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Omrežje je na voljo"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Stanje omrežja VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Skrbništvo naprave"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Opozorila"</string>
@@ -498,6 +497,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Dosežena časovna omejitev za prstni odtis. Poskusite znova."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Dejanje s prstnim odtisom je bilo preklicano."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Preveč poskusov. Poskusite znova pozneje."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Poskusite znova."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 979e561..283ec35 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Përditësimet"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Statusi i rrjetit"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Sinjalizimet e rrjetit"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Ka rrjet të disponueshëm"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Statusi i VPN-së"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Administrimi i pajisjes"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Sinjalizimet"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Koha e veprimit për gjurmën e gishtit skadoi. Provo përsëri."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operacioni i gjurmës së gishtit u anulua."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Keni bërë shumë tentativa. Provo përsëri më vonë."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Provo përsëri."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 9024d70..3b4d194 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -263,8 +263,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Ажурирања"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Статус мреже"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Обавештења у вези са мрежом"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Мрежа је доступна"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Статус VPN-а"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Администрирање уређаја"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Обавештења"</string>
@@ -495,6 +494,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Временско ограничење за отисак прста је истекло. Пробајте поново."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Радња са отиском прста је отказана."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Превише покушаја. Пробајте поново касније."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Пробајте поново."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 089c97c..8c6071c 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tidsgränsen för fingeravtrycket har uppnåtts. Försök igen."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingeravtrycksåtgärden avbröts."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Du har gjort för många försök. Försök igen senare."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Försök igen."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index cdb2cd3..21a5271 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -207,7 +207,7 @@
     <string name="reboot_to_update_prepare" msgid="6305853831955310890">"Inajiandaa kusasisha..."</string>
     <string name="reboot_to_update_package" msgid="3871302324500927291">"Inachakata kifurushi cha kusasisha…"</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"Inazima na kuwasha upya..."</string>
-    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Rejesha data ya mwanzo"</string>
+    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Rejesha mipangilio ya kiwandani"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"Inazima na kuwasha upya..."</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"Inafunga..."</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Kompyuta kibao yako itazima."</string>
@@ -258,8 +258,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Taarifa"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Hali ya mtandao"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Arifa za mtandao"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Mtandao unapatikana"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Hali ya VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Udhibiti wa kifaa"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Arifa"</string>
@@ -490,6 +489,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Muda wa kitambulisho umekwisha. Jaribu tena."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Utendaji wa kitambulisho imeghairiwa."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Majaribio mengi mno. Jaribu tena baadaye."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Jaribu tena."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Kitambulisho <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
@@ -569,7 +570,7 @@
     <string name="policylab_forceLock" msgid="2274085384704248431">"Kufunga skrini"</string>
     <string name="policydesc_forceLock" msgid="1141797588403827138">"Kudhibiti jinsi na wakati skrini inapofunga."</string>
     <string name="policylab_wipeData" msgid="3910545446758639713">"Kufuta data yote"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Futa data ya kompyuta kibao bila ilani kwa kurejesha mipangilio ya mwanzo."</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Futa data ya kompyuta kibao bila ilani kwa kurejesha mipangilio ambayo kompyuta ilitoka nayo kiwandani."</string>
     <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Futa data ya runinga bila onyo kwa kurejesha katika hali iliyotoka nayo kiwandani."</string>
     <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Kufuta data ya simu bila ilani kwa kurejesha data ambayo kifaa kilitoka nayo kiwandani"</string>
     <string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"Futa data yote ya mtumiaji"</string>
@@ -749,9 +750,9 @@
     <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Umekosea katika kuweka mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%2$d</xliff:g> bila kufaulu, utaulizwa kufungua kompyuta yako ndogo kwa kuingia kwa Google.\n\n Jaribu tena katika sekunde <xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Umekosea kuchora mchoro wa kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Ukikosea majaribio mengine <xliff:g id="NUMBER_1">%2$d</xliff:g>, utaombwa ufungue runinga yako ukitumia Google.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%2$d</xliff:g> yasiyofaulu, utaulizwa kufungua simu kupitia kuingia Google.\n\n Jaribu tena katika sekunde <xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Baada ya zaidi ya <xliff:g id="NUMBER_1">%2$d</xliff:g> majaribio yasiyofanikiwa, kompyuta ndogo itawekwa upya kwa kiwanda chaguo-msingi na data yote ya mtumiaji itapotea."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Umejaribu kufungua kompyuta kibao kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Ukijaribu tena mara <xliff:g id="NUMBER_1">%2$d</xliff:g> bila mafanikio, kompyuta ndogo itarejeshwa kwenye mipangilio iliyotoka nayo kiwandani na data yote iliyomo itafutwa."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Umekosea majaribio ya kufungua runinga mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Ukikosea majaribio <xliff:g id="NUMBER_1">%2$d</xliff:g> zaidi, runinga itarejeshwa katika hali iliyotoka nayo kiwandani na data yote ya watumiaji itafutwa."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Umejaribu kufungua simu kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%2$d</xliff:g> zaidi yasiyofanikiwa, simu itawekwa upya kwa kiwanda chaguo-msingi na data yote ya mtumiaji itapotea."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Umejaribu kufungua simu kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Ukijaribu tena mara <xliff:g id="NUMBER_1">%2$d</xliff:g> bila mafanikio, simu itarejeshwa kwenye mipangilio iliyotoka nayo kiwandani na data yote iliyomo itafutwa."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER">%d</xliff:g>. Kompyuta ndogo haitaweza kuwekwa upya kwa kiwanda chaguo-msingi."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Umekosea majaribio ya kufungua runinga mara <xliff:g id="NUMBER">%d</xliff:g>. Sasa runinga itarejeshwa katika mipangilio iliyotoka nayo kiwandani."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER">%d</xliff:g>. Kompyuta ndogo haitaweza kuwekwa upya kwa kiwanda chaguo-msingi."</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 5838ef2..0c9a263 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"புதுப்பிப்புகள்"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"நெட்வொர்க்கின் நிலை"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"நெட்வொர்க் விழிப்பூட்டல்கள்"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"நெட்வொர்க் உள்ளது"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN நிலை"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"சாதன நிர்வாகம்"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"விழிப்பூட்டல்கள்"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"கைரேகைக்கான நேரம் முடிந்தது. மீண்டும் முயலவும்."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"கைரேகை செயல்பாடு ரத்துசெய்யப்பட்டது."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"அதிகமான முயற்சிகள். பிறகு முயற்சிக்கவும்."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"மீண்டும் முயற்சிக்கவும்."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"கைரேகை <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 2249d0f..adfe2c4 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"వేలిముద్ర గడువు సమయం చేరుకుంది. మళ్లీ ప్రయత్నించండి."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"వేలిముద్ర కార్యాచరణ రద్దయింది."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"చాలా ఎక్కువ ప్రయత్నాలు చేసారు. తర్వాత మళ్లీ ప్రయత్నించండి."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"మళ్లీ ప్రయత్నించండి."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"వేలు <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 72414fb..a1d7faa 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"การอัปเดต"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"สถานะเครือข่าย"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"การแจ้งเตือนเครือข่าย"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"มีเครือข่ายพร้อมใช้งาน"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"สถานะ VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"การดูแลระบบอุปกรณ์"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"การแจ้งเตือน"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"หมดเวลาใช้ลายนิ้วมือแล้ว โปรดลองอีกครั้ง"</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"ยกเลิกการทำงานของลายนิ้วมือ"</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"ดำเนินการหลายครั้งเกินไป ลองอีกครั้งในภายหลัง"</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"ลองอีกครั้ง"</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"นิ้ว <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index dee258f..a28050f 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Mga Update"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Status ng network"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Mga alerto sa network"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Available ang network"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Status ng VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Pamamahala ng device"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Mga Alerto"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Nag-time out ang fingerprint. Subukang muli."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Nakansela ang operasyong ginagamitan ng fingerprint."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Masyadong maraming beses sumubok. Subukang muli sa ibang pagkakataon."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Subukang muli."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Daliri <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 91dfb67..e447d73 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Parmak izi için zaman aşımı oluştu. Tekrar deneyin."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Parmak izi işlemi iptal edildi."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Çok fazla deneme yapıldı. Daha sonra tekrar deneyin."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Tekrar deneyin."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g>. parmak"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 7fa5e51..f7942ac 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -266,8 +266,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Оновлення"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Статус мережі"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Сповіщення мережі"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Мережа доступна"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Статус мережі VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Адміністрування пристрою"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Сповіщення"</string>
@@ -498,6 +497,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Час очікування відбитка минув. Повторіть спробу."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Дію з відбитком скасовано."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Забагато спроб. Спробуйте пізніше."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Повторіть спробу."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Відбиток пальця <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 5e79088..1c1b2a8 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"فنگر پرنٹ کی میعاد ختم ہوگئی۔ دوبارہ کوشش کریں۔"</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"فنگر پرنٹ کی کارروائی منسوخ ہوگئی۔"</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"کافی زیادہ کوششیں کی گئیں۔ بعد میں دوبارہ کوشش کریں۔"</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"دوبارہ کوشش کریں۔"</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 68cf928..52f7d79 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Yangilanishlar"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Tarmoq holati"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Tarmoqqa oid bildirgilar"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Tarmoq mavjud"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN holati"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Qurilma boshqaruvi"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Ogohlantirishlar"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Barmoq izini aniqlash vaqti tugab qoldi. Qayta urinib ko‘ring."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Barmoq izi tekshiruvi bekor qilindi."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Urinishlar soni ko‘payib ketdi. Keyinroq qayta urinib ko‘ring."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Qayta urinib ko‘ring."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Barmoq izi <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
@@ -770,7 +771,7 @@
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Tekshirilmoqda…"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Qulfdan chiqarish"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ovozni yoqish"</string>
-    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Ovozni o‘chirish"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Ovozsiz qilish"</string>
     <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Grafik kalitni chizish boshlandi"</string>
     <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Grafik kalit tozalandi"</string>
     <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Katak qo‘shildi"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index a200a12..db8df0d 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Cập nhật"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Trạng thái mạng"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Cảnh báo mạng"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Có mạng"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Trạng thái VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Quản lý thiết bị"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Cảnh báo"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Đã hết thời gian chờ vân tay. Hãy thử lại."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Thao tác dùng dấu vân tay bị hủy."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Quá nhiều lần thử. Hãy thử lại sau."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Thử lại."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Ngón tay <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index de2a965..89b2e57 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"指纹录入操作超时,请重试。"</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"指纹操作已取消。"</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"尝试次数过多,请稍后重试。"</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"请重试。"</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index e8ae0d9..c5ec77c 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"指紋已逾時。請再試一次。"</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"指紋操作已取消。"</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"嘗試次數過多,請稍後再試。"</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"再試一次。"</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index ecd7ace..6e63cee 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -492,6 +492,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"指紋處理作業逾時,請再試一次。"</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"指紋作業已取消。"</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"嘗試次數過多,請稍後再試。"</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"請再試一次。"</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index d45d2b6..1900f8b 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -260,8 +260,7 @@
     <string name="notification_channel_updates" msgid="4794517569035110397">"Izibuyekezo"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Isimo senethiwekhi"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Izexwayiso zenethiwekhi"</string>
-    <!-- no translation found for notification_channel_network_available (4531717914138179517) -->
-    <skip />
+    <string name="notification_channel_network_available" msgid="4531717914138179517">"Inethiwekhi iyatholakala"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"Isimo se-VPN"</string>
     <string name="notification_channel_device_admin" msgid="1568154104368069249">"Ukulawula idivayisi"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Izexwayiso"</string>
@@ -492,6 +491,8 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Kufinyelelwe isikhathi sokuvala sezigxivizo zeminwe. Zama futhi"</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Ukusebenza kwezingxivizo zeminwe kukhanseliwe."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Imizamo eminingi kakhulu. Zama futhi emuva kwesikhathi."</string>
+    <!-- no translation found for fingerprint_error_lockout_permanent (5033251797919508137) -->
+    <skip />
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Zama futhi."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Umunwe ongu-<xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b557ace..c7b0b35 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2908,6 +2908,11 @@
     <!-- Default data warning level in mb -->
     <integer name="default_data_warning_level_mb">2048</integer>
 
+    <!-- When true, indicates that the vendor's IMS implementation requires a workaround when
+     sending a request to enable or disable the camera while the video session is also
+     paused. -->
+    <bool name="config_useVideoPauseWorkaround">false</bool>
+
     <!-- Whether to send a custom package name with the PSD.-->
     <bool name="config_sendPackageName">false</bool>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3f36fd1..aa586b7 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3020,7 +3020,7 @@
   <java-symbol type="bool" name="enable_pbap_pce_profile" />
 
   <java-symbol type="integer" name="default_data_warning_level_mb" />
-
+  <java-symbol type="bool" name="config_useVideoPauseWorkaround" />
   <java-symbol type="bool" name="config_sendPackageName" />
   <java-symbol type="string" name="config_helpPackageNameKey" />
   <java-symbol type="string" name="config_helpPackageNameValue" />
diff --git a/core/tests/coretests/res/layout/messaging_linear_layout_test.xml b/core/tests/coretests/res/layout/messaging_linear_layout_test.xml
index 8ba3e07..9e70ca3 100644
--- a/core/tests/coretests/res/layout/messaging_linear_layout_test.xml
+++ b/core/tests/coretests/res/layout/messaging_linear_layout_test.xml
@@ -19,7 +19,6 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:maxHeight="300px"
     android:spacing="5px">
 
 </com.android.internal.widget.MessagingLinearLayout>
\ No newline at end of file
diff --git a/core/tests/coretests/src/android/app/LoaderLifecycleTest.java b/core/tests/coretests/src/android/app/LoaderLifecycleTest.java
index 1850d57..c83e798 100644
--- a/core/tests/coretests/src/android/app/LoaderLifecycleTest.java
+++ b/core/tests/coretests/src/android/app/LoaderLifecycleTest.java
@@ -17,6 +17,13 @@
 
 package android.app;
 
+import static junit.framework.TestCase.assertNotNull;
+import static junit.framework.TestCase.assertNotSame;
+import static junit.framework.TestCase.assertSame;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import android.content.Context;
 import android.os.Handler;
 import android.os.Parcelable;
@@ -24,14 +31,11 @@
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.ArrayMap;
+
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import static junit.framework.TestCase.assertNotNull;
-import static junit.framework.TestCase.assertNotSame;
-import static junit.framework.TestCase.assertSame;
-
 @RunWith(AndroidJUnit4.class)
 public class LoaderLifecycleTest {
     @Rule
@@ -203,6 +207,16 @@
 
             // Test that the fragments are in the configuration we expect
             final Fragment restoredOne = fm2.findFragmentByTag("one");
+            try {
+                restoredOne.getLoaderManager();
+                fail("A restored fragment on the back stack doesn't have a host, so it should "
+                        + "throw an exception");
+            } catch (IllegalStateException e) {
+                // expected
+            }
+            fm2.popBackStackImmediate();
+            // Now restoredOne should be added and should be in a good state.
+            assertTrue(restoredOne.isAdded());
             final LoaderManager lm2 = restoredOne.getLoaderManager();
 
             assertSame("didn't get same LoaderManager instance back", lm2, lm1);
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 698f2ec..423d45ea 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -1323,24 +1323,8 @@
             return;
         }
         Runtime.getRuntime().gc();
-
-        final String packageName = ip.pkg.packageName;
-        Log.i(TAG, "Deleting package : " + packageName);
-
-        ApplicationInfo info = null;
         try {
-            info = getPm().getApplicationInfo(packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES);
-        } catch (NameNotFoundException ignored) {
-        }
-
-        DeleteObserver observer = new DeleteObserver(packageName);
-        getPm().deletePackage(packageName, observer, PackageManager.DELETE_ALL_USERS);
-        observer.waitForCompletion(MAX_WAIT_TIME);
-
-        try {
-            if (info != null) {
-                assertUninstalled(info);
-            }
+            cleanUpInstall(ip.pkg.packageName);
         } finally {
             File outFile = new File(ip.pkg.codePath);
             if (outFile != null && outFile.exists()) {
@@ -1355,16 +1339,15 @@
         }
         Log.i(TAG, "Deleting package : " + pkgName);
         try {
-            ApplicationInfo info = getPm().getApplicationInfo(pkgName,
+            final ApplicationInfo info = getPm().getApplicationInfo(pkgName,
                     PackageManager.MATCH_UNINSTALLED_PACKAGES);
-
             if (info != null) {
                 DeleteObserver observer = new DeleteObserver(pkgName);
                 getPm().deletePackage(pkgName, observer, PackageManager.DELETE_ALL_USERS);
                 observer.waitForCompletion(MAX_WAIT_TIME);
                 assertUninstalled(info);
             }
-        } catch (NameNotFoundException e) {
+        } catch (IllegalArgumentException | NameNotFoundException e) {
         }
     }
 
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 5debd7e..02ff209 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -399,8 +399,6 @@
                  Settings.Secure.ANR_SHOW_BACKGROUND,
                  Settings.Secure.ASSISTANT,
                  Settings.Secure.ASSIST_DISCLOSURE_ENABLED,
-                 Settings.Secure.ASSIST_GESTURE_ENABLED_KEYGUARD,
-                 Settings.Secure.ASSIST_GESTURE_ENABLED_SLEEP,
                  Settings.Secure.ASSIST_SCREENSHOT_ENABLED,
                  Settings.Secure.ASSIST_STRUCTURE_ENABLED,
                  Settings.Secure.AUTOFILL_SERVICE_SEARCH_URI,
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
index d8de70c..9aabdbb 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
@@ -100,6 +100,55 @@
         assertEquals(227_000, bgtb.computeRealtime(cur, STATS_SINCE_CHARGED));
     }
 
+    /** Test that BatteryStatsImpl.Uid.mOnBatteryScreenOffBackgroundTimeBase works correctly. */
+    @SmallTest
+    public void testScreenOffBgTimeBase() throws Exception {
+        final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
+        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
+        long cur = 0; // realtime in us
+
+        BatteryStatsImpl.TimeBase bgtb = bi.getOnBatteryScreenOffBackgroundTimeBase(UID);
+
+        // battery=off, screen=off, background=off
+        cur = (clocks.realtime = clocks.uptime = 100) * 1000;
+        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
+        bi.updateTimeBasesLocked(false, false, cur, cur);
+        assertFalse(bgtb.isRunning());
+
+        // battery=on, screen=off, background=off
+        cur = (clocks.realtime = clocks.uptime = 200) * 1000;
+        bi.updateTimeBasesLocked(true, false, cur, cur);
+        assertFalse(bgtb.isRunning());
+
+        // battery=on, screen=on, background=off
+        cur = (clocks.realtime = clocks.uptime = 300) * 1000;
+        bi.updateTimeBasesLocked(true, true, cur, cur);
+        assertFalse(bgtb.isRunning());
+
+        // battery=on, screen=on, background=on
+        // Only during this period should the timebase progress
+        cur = (clocks.realtime = clocks.uptime = 400) * 1000;
+        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+        assertTrue(bgtb.isRunning());
+
+        // battery=on, screen=off, background=on
+        cur = (clocks.realtime = clocks.uptime = 550) * 1000;
+        bi.updateTimeBasesLocked(true, false, cur, cur);
+        assertFalse(bgtb.isRunning());
+
+        // battery=off, screen=off, background=on
+        cur = (clocks.realtime = clocks.uptime = 660) * 1000;
+        bi.updateTimeBasesLocked(false, false, cur, cur);
+        assertFalse(bgtb.isRunning());
+
+        // battery=off, screen=off, background=off
+        cur = (clocks.realtime = clocks.uptime = 770) * 1000;
+        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
+        assertFalse(bgtb.isRunning());
+
+        assertEquals(150_000, bgtb.computeRealtime(cur, STATS_SINCE_CHARGED));
+    }
+
     @SmallTest
     public void testWifiScan() throws Exception {
         final MockClocks clocks = new MockClocks();
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
index e374e11..06ca18d 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
@@ -16,7 +16,10 @@
 package com.android.internal.os;
 
 import static android.os.BatteryStats.STATS_SINCE_CHARGED;
+import static android.os.BatteryStats.WAKE_TYPE_PARTIAL;
 
+import android.app.ActivityManager;
+import android.os.BatteryStats;
 import android.os.WorkSource;
 import android.support.test.filters.SmallTest;
 
@@ -29,7 +32,7 @@
     private static final int UID = 10500;
     private static final WorkSource WS = new WorkSource(UID);
 
-    /** Test that BatteryStatsImpl.Uid.noteBluetoothScanResultsLocked. */
+    /** Test BatteryStatsImpl.Uid.noteBluetoothScanResultLocked. */
     @SmallTest
     public void testNoteBluetoothScanResultLocked() throws Exception {
         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(new MockClocks());
@@ -41,4 +44,30 @@
                 bi.getUidStats().get(UID).getBluetoothScanResultCounter()
                         .getCountLocked(STATS_SINCE_CHARGED));
     }
+
+    /** Test BatteryStatsImpl.Uid.noteStartWakeLocked. */
+    @SmallTest
+    public void testNoteStartWakeLocked() throws Exception {
+        final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
+        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
+
+        int pid = 10;
+        String name = "name";
+
+        bi.updateTimeBasesLocked(true, true, 0, 0);
+        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
+        bi.getUidStatsLocked(UID).noteStartWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime);
+
+        clocks.realtime = clocks.uptime = 100;
+        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+
+        clocks.realtime = clocks.uptime = 220;
+        bi.getUidStatsLocked(UID).noteStopWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime);
+
+        BatteryStats.Timer aggregTimer = bi.getUidStats().get(UID).getAggregatedPartialWakelockTimer();
+        long actualTime = aggregTimer.getTotalTimeLocked(300_000, STATS_SINCE_CHARGED);
+        long bgTime = aggregTimer.getSubTimer().getTotalTimeLocked(300_000, STATS_SINCE_CHARGED);
+        assertEquals(220_000, actualTime);
+        assertEquals(120_000, bgTime);
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java
index ad8221b..620acae 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java
@@ -18,6 +18,7 @@
 
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.support.test.filters.SmallTest;
@@ -27,6 +28,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 import java.io.BufferedReader;
@@ -70,18 +72,70 @@
                 times[i][j] = uids[i] * freqs[j] * 10;
             }
         }
-        final String[] uidsTimesLines = getUidTimesLines(uids, times);
-        final String[] lines = new String[uidsTimesLines.length + 1];
-        System.arraycopy(uidsTimesLines, 0, lines, 0, uidsTimesLines.length);
-        lines[uidsTimesLines.length] = null;
         when(mBufferedReader.readLine())
-                .thenReturn(getFreqsLine(freqs), lines);
+                .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, times));
         mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
         verify(mCallback).onCpuFreqs(freqs);
         for (int i = 0; i < uids.length; ++i) {
             verify(mCallback).onUidCpuFreqTime(uids[i], times[i]);
         }
         verifyNoMoreInteractions(mCallback);
+
+        // Verify that a second call will only return deltas.
+        Mockito.reset(mCallback, mBufferedReader);
+        final long[][] newTimes1 = new long[uids.length][freqs.length];
+        for (int i = 0; i < uids.length; ++i) {
+            for (int j = 0; j < freqs.length; ++j) {
+                newTimes1[i][j] = (times[i][j] + uids[i] + freqs[j]) * 10;
+            }
+        }
+        when(mBufferedReader.readLine())
+                .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes1));
+        mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
+        verify(mCallback).onCpuFreqs(freqs);
+        for (int i = 0; i < uids.length; ++i) {
+            verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes1[i], times[i]));
+        }
+        verifyNoMoreInteractions(mCallback);
+
+        // Verify that calling with a null callback doesn't result in any crashes
+        Mockito.reset(mCallback, mBufferedReader);
+        final long[][] newTimes2 = new long[uids.length][freqs.length];
+        for (int i = 0; i < uids.length; ++i) {
+            for (int j = 0; j < freqs.length; ++j) {
+                newTimes2[i][j] = (newTimes1[i][j] + uids[i] * freqs[j]) * 10;
+            }
+        }
+        when(mBufferedReader.readLine())
+                .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes2));
+        mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, null);
+        verifyZeroInteractions(mCallback);
+
+        // Verify that the readDelta call will only return deltas when
+        // the previous call had null callback.
+        Mockito.reset(mCallback, mBufferedReader);
+        final long[][] newTimes3 = new long[uids.length][freqs.length];
+        for (int i = 0; i < uids.length; ++i) {
+            for (int j = 0; j < freqs.length; ++j) {
+                newTimes3[i][j] = (newTimes2[i][j] * (uids[i] + freqs[j])) * 10;
+            }
+        }
+        when(mBufferedReader.readLine())
+                .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes3));
+        mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
+        verify(mCallback).onCpuFreqs(freqs);
+        for (int i = 0; i < uids.length; ++i) {
+            verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes3[i], newTimes2[i]));
+        }
+        verifyNoMoreInteractions(mCallback);
+    }
+
+    private long[] subtract(long[] a1, long[] a2) {
+        long[] val = new long[a1.length];
+        for (int i = 0; i < val.length; ++i) {
+            val[i] = a1[i] - a2[i];
+        }
+        return val;
     }
 
     private String getFreqsLine(long[] freqs) {
@@ -94,7 +148,7 @@
     }
 
     private String[] getUidTimesLines(int[] uids, long[][] times) {
-        final String[] lines = new String[uids.length];
+        final String[] lines = new String[uids.length + 1];
         final StringBuilder sb = new StringBuilder();
         for (int i = 0; i < uids.length; ++i) {
             sb.setLength(0);
@@ -104,6 +158,7 @@
             }
             lines[i] = sb.toString();
         }
+        lines[uids.length] = null;
         return lines;
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/os/LongSamplingCounterArrayTest.java b/core/tests/coretests/src/com/android/internal/os/LongSamplingCounterArrayTest.java
new file mode 100644
index 0000000..4a23f40
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/LongSamplingCounterArrayTest.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.internal.os;
+
+import static android.os.BatteryStats.STATS_SINCE_CHARGED;
+
+import static com.android.internal.os.BatteryStatsImpl.LongSamplingCounterArray;
+import static com.android.internal.os.BatteryStatsImpl.TimeBase;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Arrays;
+
+/**
+ * Test class for {@link BatteryStatsImpl.LongSamplingCounterArray}.
+ *
+ * To run the tests, use
+ *
+ * runtest -c com.android.internal.os.LongSamplingCounterArrayTest frameworks-core
+ *
+ * or the following steps:
+ *
+ * Build: m FrameworksCoreTests
+ * Install: adb install -r \
+ *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk
+ * Run: adb shell am instrument -e class com.android.internal.os.LongSamplingCounterArrayTest -w \
+ *     com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class LongSamplingCounterArrayTest {
+
+    private static final long[] COUNTS = {1111, 2222, 3333, 4444};
+    private static final long[] LOADED_COUNTS = {5555, 6666, 7777, 8888};
+    private static final long[] PLUGGED_COUNTS = {9999, 11111, 22222, 33333};
+    private static final long[] UNPLUGGED_COUNTS = {44444, 55555, 66666, 77777};
+    private static final long[] ZEROES = {0, 0, 0, 0};
+
+    @Mock private TimeBase mTimeBase;
+    private LongSamplingCounterArray mCounterArray;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mCounterArray = new LongSamplingCounterArray(mTimeBase);
+        Mockito.reset(mTimeBase);
+    }
+
+    @Test
+    public void testReadWriteParcel() {
+        final Parcel parcel = Parcel.obtain();
+        initializeCounterArrayWithDefaultValues();
+        LongSamplingCounterArray.writeToParcel(parcel, mCounterArray);
+        parcel.setDataPosition(0);
+
+        // Now clear counterArray and verify values are read from parcel correctly.
+        updateCounts(null, null, null, null);
+        mCounterArray = LongSamplingCounterArray.readFromParcel(parcel, mTimeBase);
+        assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
+        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
+        assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
+        assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
+                "Unexpected unpluggedCounts");
+        parcel.recycle();
+    }
+
+    @Test
+    public void testReadWriteSummaryParcel() {
+        final Parcel parcel = Parcel.obtain();
+        initializeCounterArrayWithDefaultValues();
+        LongSamplingCounterArray.writeSummaryToParcelLocked(parcel, mCounterArray);
+        parcel.setDataPosition(0);
+
+        // Now clear counterArray and verify values are read from parcel correctly.
+        updateCounts(null, null, null, null);
+        mCounterArray = LongSamplingCounterArray.readSummaryFromParcelLocked(parcel, mTimeBase);
+        assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
+        assertArrayEquals(COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
+        assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
+        assertArrayEquals(COUNTS, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
+        parcel.recycle();
+    }
+
+    @Test
+    public void testOnTimeStarted() {
+        initializeCounterArrayWithDefaultValues();
+        mCounterArray.onTimeStarted(0, 0, 0);
+        assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mCounts, "Unexpected counts");
+        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
+        assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
+        assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
+                "Unexpected unpluggedCounts");
+    }
+
+    @Test
+    public void testOnTimeStopped() {
+        initializeCounterArrayWithDefaultValues();
+        mCounterArray.onTimeStopped(0, 0, 0);
+        assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
+        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
+        assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
+        assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
+                "Unexpected unpluggedCounts");
+    }
+
+    @Test
+    public void testGetCountsLocked() {
+        initializeCounterArrayWithDefaultValues();
+
+        when(mTimeBase.isRunning()).thenReturn(false);
+        long[] actualVal = mCounterArray.getCountsLocked(STATS_SINCE_CHARGED);
+        long[] expectedVal = PLUGGED_COUNTS;
+        assertArrayEquals(expectedVal, actualVal, "Unexpected values");
+
+        when(mTimeBase.isRunning()).thenReturn(true);
+        actualVal = mCounterArray.getCountsLocked(STATS_SINCE_CHARGED);
+        expectedVal = COUNTS;
+        assertArrayEquals(expectedVal, actualVal, "Unexpected values");
+    }
+
+    @Test
+    public void testAddCountLocked() {
+        final long[] deltas = {123, 234, 345, 456};
+        mCounterArray.addCountLocked(deltas);
+        assertArrayEquals(deltas, mCounterArray.mCounts, "Unexpected counts");
+        assertArrayEquals(null, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
+        assertArrayEquals(null, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
+        assertArrayEquals(null, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
+
+        initializeCounterArrayWithDefaultValues();
+        final long[] newCounts = new long[deltas.length];
+        for (int i = 0; i < deltas.length; ++i) {
+            newCounts[i] = COUNTS[i] + deltas[i];
+        }
+        mCounterArray.addCountLocked(deltas);
+        assertArrayEquals(newCounts, mCounterArray.mCounts, "Unexpected counts");
+        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
+        assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
+        assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
+                "Unexpected unpluggedCounts");
+    }
+
+    @Test
+    public void testReset() {
+        initializeCounterArrayWithDefaultValues();
+        // Test with detachIfReset=false
+        mCounterArray.reset(false /* detachIfReset */);
+        assertArrayEquals(ZEROES, mCounterArray.mCounts, "Unexpected counts");
+        assertArrayEquals(ZEROES, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
+        assertArrayEquals(ZEROES, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
+        assertArrayEquals(ZEROES, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
+        verifyZeroInteractions(mTimeBase);
+
+        initializeCounterArrayWithDefaultValues();
+        // Test with detachIfReset=true
+        mCounterArray.reset(true /* detachIfReset */);
+        assertArrayEquals(ZEROES, mCounterArray.mCounts, "Unexpected counts");
+        assertArrayEquals(ZEROES, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
+        assertArrayEquals(ZEROES, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
+        assertArrayEquals(ZEROES, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
+        verify(mTimeBase).remove(mCounterArray);
+        verifyNoMoreInteractions(mTimeBase);
+    }
+
+    @Test
+    public void testDetach() {
+        mCounterArray.detach();
+        verify(mTimeBase).remove(mCounterArray);
+        verifyNoMoreInteractions(mTimeBase);
+    }
+
+    private void initializeCounterArrayWithDefaultValues() {
+        updateCounts(COUNTS, LOADED_COUNTS, PLUGGED_COUNTS, UNPLUGGED_COUNTS);
+    }
+
+    private void assertArrayEquals(long[] expected, long[] actual, String msg) {
+        assertTrue(msg + ", expected: " + Arrays.toString(expected)
+                + ", actual: " + Arrays.toString(actual), Arrays.equals(expected, actual));
+    }
+
+    private void updateCounts(long[] counts, long[] loadedCounts,
+            long[] pluggedCounts, long[] unpluggedCounts) {
+        mCounterArray.mCounts = counts;
+        mCounterArray.mLoadedCounts = loadedCounts;
+        mCounterArray.mPluggedCounts = pluggedCounts;
+        mCounterArray.mUnpluggedCounts = unpluggedCounts;
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java
index 65f898c..a123fce 100644
--- a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java
+++ b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java
@@ -44,5 +44,9 @@
     public TimeBase getOnBatteryBackgroundTimeBase(int uid) {
         return getUidStatsLocked(uid).mOnBatteryBackgroundTimeBase;
     }
+
+    public TimeBase getOnBatteryScreenOffBackgroundTimeBase(int uid) {
+        return getUidStatsLocked(uid).mOnBatteryScreenOffBackgroundTimeBase;
+    }
 }
 
diff --git a/core/tests/coretests/src/com/android/internal/widget/ImageFloatingTextViewTest.java b/core/tests/coretests/src/com/android/internal/widget/ImageFloatingTextViewTest.java
index 5dc07c2..906d7e9 100644
--- a/core/tests/coretests/src/com/android/internal/widget/ImageFloatingTextViewTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/ImageFloatingTextViewTest.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.widget;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
 import android.support.test.InstrumentationRegistry;
@@ -111,6 +111,9 @@
         mTextView.measure(widthMeasureSpec, heightMeasureSpec);
         mView.measure(widthMeasureSpec, heightMeasureSpec);
 
-        assertEquals(mTextView.getMeasuredHeight(), mView.getMeasuredHeight());
+        // We're at most allowed to be the same height as the regular textview and maybe a bit
+        // smaller since our layout snaps to full textlines.
+        assertTrue("The measured view should never be taller then the normal textview!",
+                mView.getMeasuredHeight() <= mTextView.getMeasuredHeight());
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/widget/MessagingLinearLayoutTest.java b/core/tests/coretests/src/com/android/internal/widget/MessagingLinearLayoutTest.java
index 75b2c1d..20fd4d3 100644
--- a/core/tests/coretests/src/com/android/internal/widget/MessagingLinearLayoutTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/MessagingLinearLayoutTest.java
@@ -21,7 +21,6 @@
 import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
-import android.os.Debug;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.espresso.core.deps.guava.base.Function;
 import android.support.test.filters.SmallTest;
@@ -46,8 +45,7 @@
     @Before
     public void setup() {
         mContext = InstrumentationRegistry.getTargetContext();
-        // maxHeight: 300px
-        // spacing: 50px
+        // spacing: 5px
         mView = (MessagingLinearLayout) LayoutInflater.from(mContext).inflate(
                 R.layout.messaging_linear_layout_test, null);
     }
@@ -81,8 +79,8 @@
 
         assertEquals(3, child1.getNumIndentLines());
         assertEquals(0, child2.getNumIndentLines());
-        assertFalse(child1.isHidden());
-        assertFalse(child2.isHidden());
+        assertFalse("child1 should not be hidden", child1.isHidden());
+        assertFalse("child2 should not be hidden", child2.isHidden());
         assertEquals(205, mView.getMeasuredHeight());
     }
 
@@ -100,8 +98,8 @@
 
         assertEquals(2, child1.getNumIndentLines());
         assertEquals(1, child2.getNumIndentLines());
-        assertFalse(child1.isHidden());
-        assertFalse(child2.isHidden());
+        assertFalse("child1 should not be hidden", child1.isHidden());
+        assertFalse("child2 should not be hidden", child2.isHidden());
         assertEquals(105, mView.getMeasuredHeight());
     }
 
@@ -118,14 +116,14 @@
         mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
 
         assertEquals(3, child2.getNumIndentLines());
-        assertTrue(child1.isHidden());
-        assertFalse(child2.isHidden());
-        assertEquals(300, mView.getMeasuredHeight());
+        assertTrue("child1 should be hidden", child1.isHidden());
+        assertFalse("child2 should not be hidden", child2.isHidden());
+        assertEquals(350, mView.getMeasuredHeight());
     }
 
     @Test
-    public void testLargeSmall_largeWrapsWith3indentbutnot3_andHitsMax() {
-        FakeImageFloatingTextView child1 = fakeChild((i) -> i > 2 ? 5 : 4);
+    public void testLargeSmall_largeWrapsWith3indentbutNotFullHeight_andHitsMax() {
+        FakeImageFloatingTextView child1 = fakeChild((i) -> i > 2 ? 7 : 6);
         FakeImageFloatingTextView child2 = fakeChild((i) -> 1);
 
         mView.setNumIndentLines(2);
@@ -135,10 +133,11 @@
         mView.measure(WIDTH_SPEC, HEIGHT_SPEC);
         mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
 
-        assertTrue(child1.isHidden());
-        assertFalse(child2.isHidden());
-        assertEquals(50, mView.getMeasuredHeight());
-        assertEquals(2, child2.getNumIndentLines());
+        assertFalse("child1 should not be hidden", child1.isHidden());
+        assertFalse("child2 should not be hidden", child2.isHidden());
+        assertEquals(355, mView.getMeasuredHeight());
+        assertEquals(3, child1.getNumIndentLines());
+        assertEquals(0, child2.getNumIndentLines());
     }
 
     @Test
@@ -153,8 +152,8 @@
         mView.measure(WIDTH_SPEC, HEIGHT_SPEC);
         mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
 
-        assertFalse(child1.isHidden());
-        assertFalse(child2.isHidden());
+        assertFalse("child1 should not be hidden", child1.isHidden());
+        assertFalse("child2 should not be hidden", child2.isHidden());
         assertEquals(255, mView.getMeasuredHeight());
         assertEquals(3, child1.getNumIndentLines());
         assertEquals(0, child2.getNumIndentLines());
@@ -184,10 +183,23 @@
         }
 
         @Override
+        public int getLayoutHeight() {
+            return Math.max(LINE_HEIGHT, getMeasuredHeight());
+        }
+
+        @Override
         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
             setMeasuredDimension(
                     getDefaultSize(500, widthMeasureSpec),
-                    resolveSize(getDesiredHeight(), heightMeasureSpec));
+                    clampToMultiplesOfLineHeight(resolveSize(getDesiredHeight(),
+                            heightMeasureSpec)));
+        }
+
+        private int clampToMultiplesOfLineHeight(int size) {
+            if (size <= LINE_HEIGHT) {
+                return size;
+            }
+            return (size / LINE_HEIGHT) * LINE_HEIGHT;
         }
 
         @Override
diff --git a/graphics/java/android/graphics/ComposeShader.java b/graphics/java/android/graphics/ComposeShader.java
index 0b1141a..70a5f53 100644
--- a/graphics/java/android/graphics/ComposeShader.java
+++ b/graphics/java/android/graphics/ComposeShader.java
@@ -76,8 +76,9 @@
                 mShaderA.getNativeInstance(), mShaderB.getNativeInstance(), mPorterDuffMode);
     }
 
+    /** @hide */
     @Override
-    void verifyNativeInstance() {
+    protected void verifyNativeInstance() {
         if (mShaderA.getNativeInstance() != mNativeInstanceShaderA
                 || mShaderB.getNativeInstance() != mNativeInstanceShaderB) {
             // Child shader native instance has been updated,
diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java
index 8410ab2..13016ff 100644
--- a/graphics/java/android/graphics/Shader.java
+++ b/graphics/java/android/graphics/Shader.java
@@ -19,6 +19,8 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 
+import libcore.util.NativeAllocationRegistry;
+
 /**
  * Shader is the based class for objects that return horizontal spans of colors
  * during drawing. A subclass of Shader is installed in a Paint calling
@@ -26,6 +28,12 @@
  * drawn with that paint will get its color(s) from the shader.
  */
 public class Shader {
+
+    private static class NoImagePreloadHolder {
+        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+                Shader.class.getClassLoader(), nativeGetFinalizer(), 50);
+    }
+
     /**
      * @deprecated Use subclass constructors directly instead.
      */
@@ -37,6 +45,8 @@
      * is called - otherwise may be out of date with java setters/properties.
      */
     private long mNativeInstance;
+    // Runnable to do immediate destruction
+    private Runnable mCleaner;
 
     /**
      * Current matrix - always set to null if local matrix is identity.
@@ -105,9 +115,11 @@
         return 0;
     }
 
-    void discardNativeInstance() {
+    /** @hide */
+    protected final void discardNativeInstance() {
         if (mNativeInstance != 0) {
-            nativeSafeUnref(mNativeInstance);
+            mCleaner.run();
+            mCleaner = null;
             mNativeInstance = 0;
         }
     }
@@ -115,20 +127,9 @@
     /**
      * Callback for subclasses to call {@link #discardNativeInstance()} if the most recently
      * constructed native instance is no longer valid.
+     * @hide
      */
-    void verifyNativeInstance() {
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            if (mNativeInstance != 0) {
-                nativeSafeUnref(mNativeInstance);
-            }
-            mNativeInstance = -1;
-        } finally {
-            super.finalize();
-        }
+    protected void verifyNativeInstance() {
     }
 
     /**
@@ -150,20 +151,20 @@
     /**
      * @hide
      */
-    public long getNativeInstance() {
-        if (mNativeInstance == -1) {
-            throw new IllegalStateException("attempting to use a finalized Shader");
-        }
-
+    public final long getNativeInstance() {
         // verify mNativeInstance is valid
         verifyNativeInstance();
 
         if (mNativeInstance == 0) {
             mNativeInstance = createNativeInstance(mLocalMatrix == null
                     ? 0 : mLocalMatrix.native_instance);
+            mCleaner = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
+                    this, mNativeInstance);
         }
         return mNativeInstance;
     }
 
-    private static native void nativeSafeUnref(long nativeInstance);
+    private static native long nativeGetFinalizer();
+
 }
+
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 959b28b..d8207b1 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -16,7 +16,6 @@
 #include "Bitmap.h"
 
 #include "Caches.h"
-#include "pipeline/skia/SkiaOpenGLPipeline.h"
 #include "renderthread/EglManager.h"
 #include "renderthread/RenderThread.h"
 #include "renderthread/RenderProxy.h"
@@ -35,15 +34,11 @@
 #include <private/gui/ComposerService.h>
 #include <binder/IServiceManager.h>
 #include <ui/PixelFormat.h>
-#include <GrTexture.h>
 
 #include <SkCanvas.h>
-#include <SkImagePriv.h>
 
 namespace android {
 
-Mutex Bitmap::gLock;
-
 static bool computeAllocationSize(size_t rowBytes, int height, size_t* size) {
     int32_t rowBytes32 = SkToS32(rowBytes);
     int64_t bigSize = (int64_t) height * rowBytes32;
@@ -316,7 +311,8 @@
         return nullptr;
     }
     SkImageInfo info = SkImageInfo::Make(graphicBuffer->getWidth(), graphicBuffer->getHeight(),
-            kRGBA_8888_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB());
+            kRGBA_8888_SkColorType, kPremul_SkAlphaType,
+            SkColorSpace::MakeSRGB());
     return sk_sp<Bitmap>(new Bitmap(graphicBuffer.get(), info));
 }
 
@@ -396,7 +392,6 @@
         , mPixelStorageType(PixelStorageType::Hardware) {
     mPixelStorage.hardware.buffer = buffer;
     buffer->incStrong(buffer);
-    setImmutable(); // HW bitmaps are always immutable
 }
 
 Bitmap::~Bitmap() {
@@ -479,13 +474,7 @@
 void Bitmap::getSkBitmap(SkBitmap* outBitmap) {
     outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
     if (isHardware()) {
-        if (uirenderer::Properties::isSkiaEnabled()) {
-            // TODO: add color correctness for Skia pipeline - pass null color space for now
-            outBitmap->allocPixels(SkImageInfo::Make(info().width(), info().height(),
-                    info().colorType(), info().alphaType(), nullptr));
-        } else {
-            outBitmap->allocPixels(info());
-        }
+        outBitmap->allocPixels(info());
         uirenderer::renderthread::RenderProxy::copyGraphicBufferInto(graphicBuffer(), outBitmap);
         return;
     }
@@ -511,28 +500,4 @@
     return nullptr;
 }
 
-sk_sp<SkImage> Bitmap::makeImage(const uirenderer::renderthread::RenderThread* renderThread) {
-    AutoMutex _lock(gLock); //TODO: implement lock free solution
-    auto image = mImage;
-    //TODO: use new API SkImage::isValid() instead of SkImage::getTexture()->getContext()
-    if (!image.get() || (image->getTexture() && nullptr == image->getTexture()->getContext())) {
-        if (isHardware() && uirenderer::RenderPipelineType::SkiaGL
-                == uirenderer::Properties::getRenderPipelineType()) {
-            //TODO: add Vulkan support
-            if (renderThread) {
-                image = uirenderer::skiapipeline::SkiaOpenGLPipeline::makeTextureImage(
-                        *renderThread, this);
-            } else {
-                image = uirenderer::renderthread::RenderProxy::makeTextureImage(this);
-            }
-        } else {
-            SkBitmap skiaBitmap;
-            getSkBitmapForShaders(&skiaBitmap);
-            image = SkMakeImageFromRasterBitmap(skiaBitmap, kNever_SkCopyPixelsMode);
-        }
-        mImage = image;
-    }
-    return image;
-}
-
 } // namespace android
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index e650c20..9a76715 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -22,8 +22,6 @@
 #include <SkPixelRef.h>
 #include <cutils/compiler.h>
 #include <ui/GraphicBuffer.h>
-#include <utils/Mutex.h>
-#include <SkImage.h>
 
 namespace android {
 
@@ -107,13 +105,6 @@
     }
 
     GraphicBuffer* graphicBuffer();
-
-    // makeImage creates or returns a cached SkImage. Can be invoked from UI or render thread.
-    // If invoked on the render thread, then RenderThread* argument is required.
-    // If not invoked on the render thread, then RenderThread* must be nullptr.
-    // makeImage is wrapping a gralloc buffer with an EGLImage and is passing a texture to Skia.
-    // This is a temporary implementation until Skia can wrap the gralloc buffer in a SkImage.
-    sk_sp<SkImage> makeImage(const uirenderer::renderthread::RenderThread*);
 private:
     Bitmap(GraphicBuffer* buffer, const SkImageInfo& info);
     virtual ~Bitmap();
@@ -144,9 +135,6 @@
             GraphicBuffer* buffer;
         } hardware;
     } mPixelStorage;
-
-    sk_sp<SkImage> mImage;
-    static Mutex gLock;
 };
 
 } //namespace android
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
index 68a0869..e0f5e54 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
@@ -137,7 +137,6 @@
 
     float ambientAlpha = (SkiaPipeline::getAmbientShadowAlpha()/255.f)*casterAlpha;
     float spotAlpha = (SkiaPipeline::getSpotShadowAlpha()/255.f)*casterAlpha;
-    const float casterZValue = casterProperties.getZ();
 
     const RevealClip& revealClip = casterProperties.getRevealClip();
     const SkPath* revealClipPath = revealClip.getPath();
@@ -178,6 +177,7 @@
     // intersect the shadow-casting path with the reveal, if present
     if (revealClipPath) {
         Op(*casterPath, *revealClipPath, kIntersect_SkPathOp, &tmpPath);
+        tmpPath.setIsVolatile(true);
         casterPath = &tmpPath;
     }
 
@@ -186,36 +186,23 @@
         SkPath clipBoundsPath;
         clipBoundsPath.addRect(casterClipRect);
         Op(*casterPath, clipBoundsPath, kIntersect_SkPathOp, &tmpPath);
+        tmpPath.setIsVolatile(true);
         casterPath = &tmpPath;
     }
     const Vector3 lightPos = SkiaPipeline::getLightCenter();
     SkPoint3 skiaLightPos = SkPoint3::Make(lightPos.x, lightPos.y, lightPos.z);
-    if (shadowMatrix.hasPerspective() || revealClipPath || clippedToBounds) {
-        std::function<SkScalar(SkScalar, SkScalar)> casterHeightFunc;
-        if (shadowMatrix.hasPerspective()) {
-            // get the matrix with the full 3D transform
-            mat4 zMatrix;
-            caster->getRenderNode()->applyViewPropertyTransforms(zMatrix, true);
-            SkScalar A = zMatrix[2];
-            SkScalar B = zMatrix[6];
-            SkScalar C = zMatrix[mat4::kTranslateZ];
-            casterHeightFunc = [A, B, C](SkScalar x, SkScalar y) {
-                return A*x + B*y + C;  // casterZValue already baked into C
-            };
-        } else {
-            casterHeightFunc = [casterZValue] (SkScalar, SkScalar) {
-                return casterZValue;
-            };
-        }
-
-        SkShadowUtils::DrawUncachedShadow(canvas, *casterPath, casterHeightFunc, skiaLightPos,
-            SkiaPipeline::getLightRadius(), ambientAlpha, spotAlpha, SK_ColorBLACK,
-            casterAlpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : 0);
+    SkPoint3 zParams;
+    if (shadowMatrix.hasPerspective()) {
+        // get the matrix with the full 3D transform
+        mat4 zMatrix;
+        caster->getRenderNode()->applyViewPropertyTransforms(zMatrix, true);
+        zParams = SkPoint3::Make(zMatrix[2], zMatrix[6], zMatrix[mat4::kTranslateZ]);
     } else {
-        SkShadowUtils::DrawShadow(canvas, *casterPath, casterZValue, skiaLightPos,
-            SkiaPipeline::getLightRadius(), ambientAlpha, spotAlpha, SK_ColorBLACK,
-            casterAlpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : 0);
+        zParams = SkPoint3::Make(0, 0, casterProperties.getZ());
     }
+    SkShadowUtils::DrawShadow(canvas, *casterPath, zParams, skiaLightPos,
+        SkiaPipeline::getLightRadius(), ambientAlpha, spotAlpha, SK_ColorBLACK,
+        casterAlpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : 0);
 }
 
 }; // namespace skiapipeline
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index 4885873..ae13131 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -28,8 +28,6 @@
 
 #include <cutils/properties.h>
 #include <strings.h>
-#include <SkImagePriv.h>
-#include <gl/GrGLTypes.h>
 
 using namespace android::uirenderer::renderthread;
 
@@ -199,87 +197,6 @@
     }
 }
 
-static void deleteImageTexture(void* context) {
-     EGLImageKHR EGLimage = reinterpret_cast<EGLImageKHR>(context);
-     if (EGLimage != EGL_NO_IMAGE_KHR) {
-        EGLDisplay display = eglGetCurrentDisplay();
-        if (EGL_NO_DISPLAY == display) {
-            display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-        }
-        eglDestroyImageKHR(display, EGLimage);
-     }
-}
-
-sk_sp<SkImage> SkiaOpenGLPipeline::makeTextureImage(
-        const uirenderer::renderthread::RenderThread& renderThread, Bitmap* bitmap) {
-    renderThread.eglManager().initialize();
-
-    GraphicBuffer* buffer = bitmap->graphicBuffer();
-    EGLDisplay display = eglGetCurrentDisplay();
-    if (EGL_NO_DISPLAY == display) {
-        display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    }
-    LOG_ALWAYS_FATAL_IF(!bitmap->isHardware(),
-                "Texture image requires a HW bitmap.");
-    // We use an EGLImage to access the content of the GraphicBuffer
-    // The EGL image is later bound to a 2D texture
-    EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer->getNativeBuffer();
-    EGLint imageAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
-    EGLImageKHR EGLimage = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
-            clientBuffer, imageAttrs);
-    if (EGLimage == EGL_NO_IMAGE_KHR) {
-        ALOGW("Could not create EGL image, err =%s",
-                uirenderer::renderthread::EglManager::eglErrorString());
-        return nullptr;
-    }
-
-    GLuint textureId = 0;
-    glGenTextures(1, &textureId);
-    glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId);
-    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, EGLimage);
-
-    GLenum status = GL_NO_ERROR;
-    while ((status = glGetError()) != GL_NO_ERROR) {
-        ALOGW("glEGLImageTargetTexture2DOES failed (%#x)", status);
-        eglDestroyImageKHR(display, EGLimage);
-        return nullptr;
-    }
-
-    sk_sp<GrContext> grContext = sk_ref_sp(renderThread.getGrContext());
-    grContext->resetContext();
-
-    GrGLTextureInfo textureInfo;
-    textureInfo.fTarget = GL_TEXTURE_EXTERNAL_OES;
-    textureInfo.fID = textureId;
-
-    GrBackendTextureDesc textureDescription;
-    textureDescription.fWidth = bitmap->info().width();
-    textureDescription.fHeight = bitmap->info().height();
-    textureDescription.fOrigin = kTopLeft_GrSurfaceOrigin;
-    textureDescription.fTextureHandle = reinterpret_cast<GrBackendObject>(&textureInfo);
-    PixelFormat format = buffer->getPixelFormat();
-    switch (format) {
-    case PIXEL_FORMAT_RGBA_8888:
-        textureDescription.fConfig = kRGBA_8888_GrPixelConfig;
-        break;
-    case PIXEL_FORMAT_RGBA_FP16:
-        textureDescription.fConfig = kRGBA_half_GrPixelConfig;
-        break;
-    default:
-        eglDestroyImageKHR(display, EGLimage);
-        return nullptr;
-    }
-
-    // TODO: add color correctness - pass null color space for now
-    sk_sp<SkImage> image = SkImage::MakeFromTexture(grContext.get(), textureDescription,
-                bitmap->info().alphaType(), nullptr, deleteImageTexture, EGLimage);
-    if (!image.get()) {
-        eglDestroyImageKHR(display, EGLimage);
-        return nullptr;
-    }
-    return image;
-}
-
 } /* namespace skiapipeline */
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
index f3ce189..36685dd 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
@@ -46,8 +46,6 @@
     bool isContextReady() override;
 
     static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor);
-    static sk_sp<SkImage> makeTextureImage(
-            const uirenderer::renderthread::RenderThread& renderThread, Bitmap* bitmap);
 
 private:
     renderthread::EglManager& mEglManager;
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
index 1863bdc..04aeb7c 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
@@ -61,7 +61,6 @@
     textureDescription.fTextureHandle = reinterpret_cast<GrBackendObject>(&externalTexture);
 
     CopyResult copyResult = CopyResult::UnknownError;
-    // TODO: add color correctness - pass null color space for now
     sk_sp<SkImage> image(SkImage::MakeFromAdoptedTexture(grContext.get(), textureDescription));
     if (image) {
         // convert to Skia data structures
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 75fb070..75f1adc 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -159,11 +159,11 @@
     GrContext* context = thread.getGrContext();
     if (context) {
         ATRACE_FORMAT("Bitmap#prepareToDraw %dx%d", bitmap->width(), bitmap->height());
-        auto image = bitmap->makeImage(&thread);
-        if (image.get() && !bitmap->isHardware()) {
-            SkImage_pinAsTexture(image.get(), context);
-            SkImage_unpinAsTexture(image.get(), context);
-        }
+        SkBitmap skiaBitmap;
+        bitmap->getSkBitmap(&skiaBitmap);
+        sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(skiaBitmap, kNever_SkCopyPixelsMode);
+        SkImage_pinAsTexture(image.get(), context);
+        SkImage_unpinAsTexture(image.get(), context);
     }
 }
 
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index d78bca9..cf8b4dd 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -156,43 +156,57 @@
 }
 
 void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) {
-    sk_sp<SkImage> image = bitmap.makeImage(nullptr);
-    if (!bitmap.isImmutable()) {
-        mDisplayList->mMutableImages.push_back(image.get());
-    }
+    SkBitmap skBitmap;
+    bitmap.getSkBitmap(&skBitmap);
+
+    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(skBitmap, kNever_SkCopyPixelsMode);
     SkPaint tmpPaint;
     mRecorder.drawImage(image, left, top, nonAAPaint(paint, &tmpPaint));
+    // if image->unique() is true, then mRecorder.drawImage failed for some reason. It also means
+    // it is not safe to store a raw SkImage pointer, because the image object will be destroyed
+    // when this function ends.
+    if (!skBitmap.isImmutable() && image.get() && !image->unique()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
 }
 
 void SkiaRecordingCanvas::drawBitmap(Bitmap& hwuiBitmap, const SkMatrix& matrix,
         const SkPaint* paint) {
+    SkBitmap bitmap;
+    hwuiBitmap.getSkBitmap(&bitmap);
     SkAutoCanvasRestore acr(&mRecorder, true);
     concat(matrix);
-    sk_sp<SkImage> image = hwuiBitmap.makeImage(nullptr);
-    if (!hwuiBitmap.isImmutable()) {
-        mDisplayList->mMutableImages.push_back(image.get());
-    }
+    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
     SkPaint tmpPaint;
     mRecorder.drawImage(image, 0, 0, nonAAPaint(paint, &tmpPaint));
+    if (!bitmap.isImmutable() && image.get() && !image->unique()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
 }
 
 void SkiaRecordingCanvas::drawBitmap(Bitmap& hwuiBitmap, float srcLeft, float srcTop,
         float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight,
         float dstBottom, const SkPaint* paint) {
+    SkBitmap bitmap;
+    hwuiBitmap.getSkBitmap(&bitmap);
     SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom);
     SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
-    sk_sp<SkImage> image = hwuiBitmap.makeImage(nullptr);
-    if (!hwuiBitmap.isImmutable()) {
-        mDisplayList->mMutableImages.push_back(image.get());
-    }
+    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
     SkPaint tmpPaint;
     mRecorder.drawImageRect(image, srcRect, dstRect, nonAAPaint(paint, &tmpPaint));
+    if (!bitmap.isImmutable() && image.get() && !image->unique() && !srcRect.isEmpty()
+            && !dstRect.isEmpty()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
 }
 
 void SkiaRecordingCanvas::drawNinePatch(Bitmap& hwuiBitmap, const Res_png_9patch& chunk,
         float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) {
+    SkBitmap bitmap;
+    hwuiBitmap.getSkBitmap(&bitmap);
+
     SkCanvas::Lattice lattice;
-    NinePatchUtils::SetLatticeDivs(&lattice, chunk, hwuiBitmap.width(), hwuiBitmap.height());
+    NinePatchUtils::SetLatticeDivs(&lattice, chunk, bitmap.width(), bitmap.height());
 
     lattice.fFlags = nullptr;
     int numFlags = 0;
@@ -209,13 +223,13 @@
 
     lattice.fBounds = nullptr;
     SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
-    sk_sp<SkImage> image = hwuiBitmap.makeImage(nullptr);
-    if (!hwuiBitmap.isImmutable()) {
-        mDisplayList->mMutableImages.push_back(image.get());
-    }
+    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
 
     SkPaint tmpPaint;
     mRecorder.drawImageLattice(image.get(), lattice, dst, nonAAPaint(paint, &tmpPaint));
+    if (!bitmap.isImmutable() && image.get() && !image->unique() && !dst.isEmpty()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
 }
 
 }; // namespace skiapipeline
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 5c2ec0e..a1f1717 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -693,18 +693,6 @@
     }
 }
 
-CREATE_BRIDGE2(makeTextureImage, RenderThread* thread, Bitmap* bitmap) {
-    return args->thread->makeTextureImage(args->bitmap).release();
-}
-
-sk_sp<SkImage> RenderProxy::makeTextureImage(Bitmap* bitmap) {
-    SETUP_TASK(makeTextureImage);
-    args->bitmap = bitmap;
-    args->thread = &RenderThread::getInstance();
-    sk_sp<SkImage> hardwareImage(reinterpret_cast<SkImage*>(staticPostAndWait(task)));
-    return hardwareImage;
-}
-
 void RenderProxy::post(RenderTask* task) {
     mRenderThread.queue(task);
 }
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 97ad796..a60ed55 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -135,8 +135,6 @@
     static sk_sp<Bitmap> allocateHardwareBitmap(SkBitmap& bitmap);
 
     static int copyGraphicBufferInto(GraphicBuffer* buffer, SkBitmap* bitmap);
-
-    static sk_sp<SkImage> makeTextureImage(Bitmap* bitmap);
 private:
     RenderThread& mRenderThread;
     CanvasContext* mContext;
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index d62b556..1450ec9 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -17,7 +17,6 @@
 #include "RenderThread.h"
 
 #include "../renderstate/RenderState.h"
-#include "../pipeline/skia/SkiaOpenGLPipeline.h"
 #include "../pipeline/skia/SkiaOpenGLReadback.h"
 #include "CanvasContext.h"
 #include "EglManager.h"
@@ -434,24 +433,6 @@
     return next;
 }
 
-sk_sp<SkImage> RenderThread::makeTextureImage(Bitmap* bitmap) {
-    auto renderType = Properties::getRenderPipelineType();
-    sk_sp<SkImage> hardwareImage;
-    switch (renderType) {
-        case RenderPipelineType::SkiaGL:
-            hardwareImage = skiapipeline::SkiaOpenGLPipeline::makeTextureImage(*this, bitmap);
-            break;
-        case RenderPipelineType::SkiaVulkan:
-            //TODO: add Vulkan support
-            break;
-        default:
-            LOG_ALWAYS_FATAL("makeTextureImage: canvas context type %d not supported",
-                    (int32_t) renderType);
-            break;
-    }
-    return hardwareImage;
-}
-
 } /* namespace renderthread */
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 34542c6..9bc5985 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -33,7 +33,6 @@
 
 namespace android {
 
-class Bitmap;
 class DisplayEventReceiver;
 
 namespace uirenderer {
@@ -105,8 +104,6 @@
 
     VulkanManager& vulkanManager() { return *mVkManager; }
 
-    sk_sp<SkImage> makeTextureImage(Bitmap* bitmap);
-
 protected:
     virtual bool threadLoop() override;
 
diff --git a/media/java/Android.bp b/media/java/Android.bp
new file mode 100644
index 0000000..0810699
--- /dev/null
+++ b/media/java/Android.bp
@@ -0,0 +1,4 @@
+filegroup {
+    name: "IMidiDeviceServer.aidl",
+    srcs: ["android/media/midi/IMidiDeviceServer.aidl"],
+}
diff --git a/media/java/android/media/AudioFocusRequest.java b/media/java/android/media/AudioFocusRequest.java
index b1dc3ad..9841815 100644
--- a/media/java/android/media/AudioFocusRequest.java
+++ b/media/java/android/media/AudioFocusRequest.java
@@ -40,7 +40,7 @@
  * <p>When an application requests audio focus, it expresses its intention to “own” audio focus to
  * play audio. Let’s review the different types of focus requests, the return value after a request,
  * and the responses to a loss.
- * <br><b>Note:<b> applications should not play anything until granted focus.
+ * <p class="note">Note: applications should not play anything until granted focus.</p>
  *
  * <h3>The different types of focus requests</h3>
  * <p>There are four focus request types. A successful focus request with each will yield different
@@ -77,9 +77,10 @@
  *
  * <p>An {@code AudioFocusRequest} instance always contains one of the four types of requests
  * explained above. It is passed when building an {@code AudioFocusRequest} instance with its
- * builder in the {@link Builder} constructor {@link Builder#Builder(int)}, or with
- * {@link Builder#setFocusGain(int)} after copying an existing instance with
- * {@link Builder#Builder(AudioFocusRequest)}.
+ * builder in the {@link Builder} constructor
+ * {@link AudioFocusRequest.Builder#AudioFocusRequest.Builder(int)}, or
+ * with {@link AudioFocusRequest.Builder#setFocusGain(int)} after copying an existing instance with
+ * {@link AudioFocusRequest.Builder#AudioFocusRequest.Builder(AudioFocusRequest)}.
  *
  * <h3>Qualifying your focus request</h3>
  * <h4>Use case requiring a focus request</h4>
@@ -105,10 +106,11 @@
  * <h4>Pausing vs ducking</h4>
  * <p>When an application requested audio focus with
  * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, the system will duck the current focus
- * owner. Note that this behavior is <b>new for Android O<b>, whereas applications targeting SDK
- * up to API 25, applications had to implement the ducking themselves when they received a focus
+ * owner.
+ * <p class="note">Note: this behavior is <b>new for Android O</b>, whereas applications targeting
+ * SDK level up to API 25 had to implement the ducking themselves when they received a focus
  * loss of {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}.
- * <br>But ducking is not always the behavior expected by the user. A typical example is when the
+ * <p>But ducking is not always the behavior expected by the user. A typical example is when the
  * device plays driving directions while the user is listening to an audio book or podcast, and
  * expects the audio playback to pause, instead of duck, as it is hard to understand a navigation
  * prompt and spoken content at the same time. Therefore the system will not automatically duck
@@ -126,7 +128,92 @@
  * speech, you can also declare so with {@link Builder#setWillPauseWhenDucked(boolean)}, which will
  * cause the system to call your focus listener instead of automatically ducking.
  *
+ * <h4>Example</h4>
+ * <p>The example below covers the following steps to be found in any application that would play
+ * audio, and use audio focus. Here we play an audio book, and our application is intended to pause
+ * rather than duck when it loses focus. These steps consist in:
+ * <ul>
+ * <li>Creating {@code AudioAttributes} to be used for the playback and the focus request.</li>
+ * <li>Configuring and creating the {@code AudioFocusRequest} instance that defines the intended
+ *     focus behaviors.</li>
+ * <li>Requesting audio focus and checking the return code to see if playback can happen right
+ *     away, or is delayed.</li>
+ * <li>Implementing a focus change listener to respond to focus gains and losses.</li>
+ * </ul>
+ * <p>
+ * <pre class="prettyprint">
+ * // initialization of the audio attributes and focus request
+ * mAudioManager = (AudioManager) Context.getSystemService(Context.AUDIO_SERVICE);
+ * mPlaybackAttributes = new AudioAttributes.Builder()
+ *         .setUsage(AudioAttributes.USAGE_MEDIA)
+ *         .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
+ *         .build();
+ * mFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
+ *         .setAudioAttributes(mPlaybackAttributes)
+ *         .setAcceptsDelayedFocusGain(true)
+ *         .setWillPauseWhenDucked(true)
+ *         .setOnAudioFocusChangeListener(this, mMyHandler)
+ *         .build();
+ * mMediaPlayer = new MediaPlayer();
+ * mMediaPlayer.setAudioAttributes(mPlaybackAttributes);
+ * final Object mFocusLock = new Object();
+ *
+ * boolean mPlaybackDelayed = false;
+ *
+ * // requesting audio focus
+ * int res = mAudioManager.requestAudioFocus(mFocusRequest);
+ * synchronized (mFocusLock) {
+ *     if (res == AUDIOFOCUS_REQUEST_FAILED) {
+ *         mPlaybackDelayed = false;
+ *     } else if (res == AUDIOFOCUS_REQUEST_GRANTED) {
+ *         mPlaybackDelayed = false;
+ *         playbackNow();
+ *     } else if (res == AUDIOFOCUS_REQUEST_DELAYED) {
+ *        mPlaybackDelayed = true;
+ *     }
+ * }
+ *
+ * // implementation of the OnAudioFocusChangeListener
+ * &#64;Override
+ * public void onAudioFocusChange(int focusChange) {
+ *     switch (focusChange) {
+ *         case AudioManager.AUDIOFOCUS_GAIN:
+ *             if (mPlaybackDelayed || mResumeOnFocusGain) {
+ *                 synchronized (mFocusLock) {
+ *                     mPlaybackDelayed = false;
+ *                     mResumeOnFocusGain = false;
+ *                 }
+ *                 playbackNow();
+ *             }
+ *             break;
+ *         case AudioManager.AUDIOFOCUS_LOSS:
+ *             synchronized (mFocusLock) {
+ *                 // this is not a transient loss, we shouldn't automatically resume for now
+ *                 mResumeOnFocusGain = false;
+ *                 mPlaybackDelayed = false;
+ *             }
+ *             pausePlayback();
+ *             break;
+ *         case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
+ *         case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
+ *             // we handle all transient losses the same way because we never duck audio books
+ *             synchronized (mFocusLock) {
+ *                 // we should only resume if playback was interrupted
+ *                 mResumeOnFocusGain = mMediaPlayer.isPlaying();
+ *                 mPlaybackDelayed = false;
+ *             }
+ *             pausePlayback();
+ *             break;
+ *     }
+ * }
+ *
+ * // Important:
+ * // Also set "mResumeOnFocusGain" to false when the user pauses or stops playback: this way your
+ * // application doesn't automatically restart when it gains focus, even though the user had
+ * // stopped it.
+ * </pre>
  */
+
 public final class AudioFocusRequest {
 
     // default attributes for the request when not specified
@@ -244,36 +331,15 @@
 
     /**
      * Builder class for {@link AudioFocusRequest} objects.
-     * <p> Here is an example where {@code Builder} is used to define the
-     * {@link AudioFocusRequest} for requesting audio focus:
-     *
-     * <pre class="prettyprint">
-     * mAudioManager = (AudioManager) Context.getSystemService(Context.AUDIO_SERVICE);
-     * mPlaybackAttributes = new AudioAttributes.Builder()
-     *         .setUsage(AudioAttributes.USAGE_GAME)
-     *         .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
-     *         .build();
-     * mFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
-     *         .setAudioAttributes(mPlaybackAttributes)
-     *         .setAcceptsDelayedFocusGain(true)
-     *         .setOnAudioFocusChangeListener(mMyFocusListener, mMyHandler)
-     *         .build();
-     * mMediaPlayer = new MediaPlayer();
-     *  ...
-     * mMediaPlayer.setAudioAttributes(mPlaybackAttributes);
-     *  ...
-     * boolean mPlaybackAuthorized = true;;
-     * int res = mAudioManager.requestAudioFocus(mFocusRequest);
-     * if (res == AUDIOFOCUS_REQUEST_FAILED) {
-     *     mPlaybackAuthorized = false;
-     *     cancelPlayback();
-     * } else if (res == AUDIOFOCUS_REQUEST_DELAYED) {
-     *     playbackDelayed();
-     * } else { // res == AUDIOFOCUS_REQUEST_GRANTED
-     *     playbackNow();
-     * }
-     * </pre>
-     *
+     * <p>See {@link AudioFocusRequest} for an example of building an instance with this builder.
+     * <br>The default values for the instance to be built are:
+     * <table>
+     * <tr><td>focus listener and handler</td><td>none</td></tr>
+     * <tr><td>{@code AudioAttributes}</td><td>attributes with usage set to
+     *     {@link AudioAttributes#USAGE_MEDIA}</td></tr>
+     * <tr><td>pauses on duck</td><td>false</td></tr>
+     * <tr><td>supports delayed focus grant</td><td>false</td></tr>
+     * </table>
      */
     public static final class Builder {
         private OnAudioFocusChangeListener mFocusListener;
diff --git a/media/java/android/media/VolumeAutomation.java b/media/java/android/media/VolumeAutomation.java
index dff8801..ff2e645 100644
--- a/media/java/android/media/VolumeAutomation.java
+++ b/media/java/android/media/VolumeAutomation.java
@@ -31,9 +31,9 @@
      * @param configuration the {@link VolumeShaper.Configuration configuration}
      *        that specifies the curve and duration to use.
      * @return a {@code VolumeShaper} object
-     * @throws IllegalArgumentException if the configuration is not allowed by the player.
-     * @throws IllegalStateException if too many VolumeShapers are requested or the state of
-     * the player does not permit its creation (e.g. player is released).
+     * @throws IllegalArgumentException if the {@code configuration} is not allowed by the player.
+     * @throws IllegalStateException if too many {@code VolumeShaper}s are requested
+     *         or the state of the player does not permit its creation (e.g. player is released).
      */
     public @NonNull VolumeShaper createVolumeShaper(
             @NonNull VolumeShaper.Configuration configuration);
diff --git a/media/java/android/media/VolumeShaper.java b/media/java/android/media/VolumeShaper.java
index 8f4721f..3068706 100644
--- a/media/java/android/media/VolumeShaper.java
+++ b/media/java/android/media/VolumeShaper.java
@@ -31,8 +31,16 @@
 /**
  * The {@code VolumeShaper} class is used to automatically control audio volume during media
  * playback, allowing simple implementation of transition effects and ducking.
+ * It is created from implementations of {@code VolumeAutomation},
+ * such as {@code MediaPlayer} and {@code AudioTrack} (referred to as "players" below),
+ * by {@link MediaPlayer#createVolumeShaper} or {@link AudioTrack#createVolumeShaper}.
  *
- * The {@link VolumeShaper} appears as an additional scaling on the audio output,
+ * A {@code VolumeShaper} is intended for short volume changes.
+ * If the audio output sink changes during
+ * a {@code VolumeShaper} transition, the precise curve position may be lost, and the
+ * {@code VolumeShaper} may advance to the end of the curve for the new audio output sink.
+ *
+ * The {@code VolumeShaper} appears as an additional scaling on the audio output,
  * and adjusts independently of track or stream volume controls.
  */
 public final class VolumeShaper implements AutoCloseable {
@@ -52,7 +60,19 @@
 
     /**
      * Applies the {@link VolumeShaper.Operation} to the {@code VolumeShaper}.
+     *
+     * Applying {@link VolumeShaper.Operation#PLAY} after {@code PLAY}
+     * or {@link VolumeShaper.Operation#REVERSE} after
+     * {@code REVERSE} has no effect.
+     *
+     * Applying {@link VolumeShaper.Operation#PLAY} when the player
+     * hasn't started will synchronously start the {@code VolumeShaper} when
+     * playback begins.
+     *
      * @param operation the {@code operation} to apply.
+     * @throws IllegalStateException if the player is uninitialized or if there
+     *         is a critical failure. In that case, the {@code VolumeShaper} should be
+     *         recreated.
      */
     public void apply(@NonNull Operation operation) {
         /* void */ applyPlayer(new VolumeShaper.Configuration(mId), operation);
@@ -65,11 +85,24 @@
      * This allows the user to change the volume shape
      * while the existing {@code VolumeShaper} is in effect.
      *
+     * The effect of {@code replace()} is similar to an atomic close of
+     * the existing {@code VolumeShaper} and creation of a new {@code VolumeShaper}.
+     *
+     * If the {@code operation} is {@link VolumeShaper.Operation#PLAY} then the
+     * new curve starts immediately.
+     *
+     * If the {@code operation} is
+     * {@link VolumeShaper.Operation#REVERSE}, then the new curve will
+     * be delayed until {@code PLAY} is applied.
+     *
      * @param configuration the new {@code configuration} to use.
-     * @param operation the operation to apply to the {@code VolumeShaper}
+     * @param operation the {@code operation} to apply to the {@code VolumeShaper}
      * @param join if true, match the start volume of the
      *             new {@code configuration} to the current volume of the existing
      *             {@code VolumeShaper}, to avoid discontinuity.
+     * @throws IllegalStateException if the player is uninitialized or if there
+     *         is a critical failure. In that case, the {@code VolumeShaper} should be
+     *         recreated.
      */
     public void replace(
             @NonNull Configuration configuration, @NonNull Operation operation, boolean join) {
@@ -81,7 +114,14 @@
     /**
      * Returns the current volume scale attributable to the {@code VolumeShaper}.
      *
+     * This is the last volume from the {@code VolumeShaper} used for the player,
+     * or the initial volume if the {@code VolumeShaper} hasn't been started with
+     * {@link VolumeShaper.Operation#PLAY}.
+     *
      * @return the volume, linearly represented as a value between 0.f and 1.f.
+     * @throws IllegalStateException if the player is uninitialized or if there
+     *         is a critical failure.  In that case, the {@code VolumeShaper} should be
+     *         recreated.
      */
     public float getVolume() {
         return getStatePlayer(mId).getVolume();
@@ -89,7 +129,14 @@
 
     /**
      * Releases the {@code VolumeShaper} object; any volume scale due to the
-     * {@code VolumeShaper} is removed.
+     * {@code VolumeShaper} is removed after closing.
+     *
+     * If the volume does not reach 1.f when the {@code VolumeShaper} is closed
+     * (or finalized), there may be an abrupt change of volume.
+     *
+     * {@code close()} may be safely called after a prior {@code close()}.
+     * This class implements the Java {@code AutoClosable} interface and
+     * may be used with try-with-resources.
      */
     @Override
     public void close() {
@@ -107,11 +154,11 @@
 
     @Override
     protected void finalize() {
-        close(); // ensure we remove the native volume shaper
+        close(); // ensure we remove the native VolumeShaper
     }
 
     /**
-     * Internal call to apply the configuration and operation to the Player.
+     * Internal call to apply the {@code configuration} and {@code operation} to the player.
      * Returns a valid shaper id or throws the appropriate exception.
      * @param configuration
      * @param operation
@@ -137,7 +184,7 @@
             // Due to RPC handling, we translate integer codes to exceptions right before
             // delivering to the user.
             if (id == VOLUME_SHAPER_INVALID_OPERATION) {
-                throw new IllegalStateException("player or volume shaper deallocated");
+                throw new IllegalStateException("player or VolumeShaper deallocated");
             } else {
                 throw new IllegalArgumentException("invalid configuration or operation: " + id);
             }
@@ -146,9 +193,9 @@
     }
 
     /**
-     * Internal call to retrieve the current VolumeShaper state.
+     * Internal call to retrieve the current {@code VolumeShaper} state.
      * @param id
-     * @return the current {@vode VolumeShaper.State}
+     * @return the current {@code VolumeShaper.State}
      * @throws IllegalStateException if the player has been deallocated or is uninitialized.
      */
     private @NonNull VolumeShaper.State getStatePlayer(int id) {
@@ -180,6 +227,9 @@
      * by {@link VolumeShaper#replace(Configuration, Operation, boolean)
      * VolumeShaper.replace(Configuration, Operation, boolean)}
      * to replace an existing {@code configuration}.
+     * <p>
+     * The {@link AudioTrack} and {@link MediaPlayer} classes implement
+     * the {@link VolumeAutomation} interface.
      */
     public static final class Configuration implements Parcelable {
         private static final int MAXIMUM_CURVE_POINTS = 16;
@@ -485,7 +535,7 @@
 
         /**
          * @hide
-         * Constructs a volume shaper from an id.
+         * Constructs a {@code VolumeShaper} from an id.
          *
          * This is an opaque handle for controlling a {@code VolumeShaper} that has
          * already been sent to a player.  The {@code id} is returned from the
@@ -756,7 +806,7 @@
             /**
              * Sets the interpolator type.
              *
-             * If omitted the interplator type is {@link #INTERPOLATOR_TYPE_CUBIC}.
+             * If omitted the default interpolator type is {@link #INTERPOLATOR_TYPE_CUBIC}.
              *
              * @param interpolatorType method of interpolation used for the volume curve.
              *        One of {@link #INTERPOLATOR_TYPE_STEP},
@@ -802,7 +852,7 @@
             }
 
             /**
-             * Sets the volume shaper duration in milliseconds.
+             * Sets the {@code VolumeShaper} duration in milliseconds.
              *
              * If omitted, the default duration is 1 second.
              *
@@ -1059,13 +1109,13 @@
 
         /**
          * Defer playback until next operation is sent. This is used
-         * when starting a VolumeShaper effect.
+         * when starting a {@code VolumeShaper} effect.
          */
         private static final int FLAG_DEFER = 1 << 3;
 
         /**
          * Use the id specified in the configuration, creating
-         * VolumeShaper as needed; the configuration should be
+         * {@code VolumeShaper} as needed; the configuration should be
          * TYPE_SCALE.
          */
         private static final int FLAG_CREATE_IF_NEEDED = 1 << 4;
@@ -1074,18 +1124,20 @@
 
         private final int mFlags;
         private final int mReplaceId;
+        private final float mXOffset;
 
         @Override
         public String toString() {
             return "VolumeShaper.Operation{"
                     + "mFlags = 0x" + Integer.toHexString(mFlags).toUpperCase()
                     + ", mReplaceId = " + mReplaceId
+                    + ", mXOffset = " + mXOffset
                     + "}";
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(mFlags, mReplaceId);
+            return Objects.hash(mFlags, mReplaceId, mXOffset);
         }
 
         @Override
@@ -1093,10 +1145,10 @@
             if (!(o instanceof Operation)) return false;
             if (o == this) return true;
             final Operation other = (Operation) o;
-            // if xOffset (native field only) is brought into Java
-            // we need to do proper NaN comparison as that is allowed.
+
             return mFlags == other.mFlags
-                    && mReplaceId == other.mReplaceId;
+                    && mReplaceId == other.mReplaceId
+                    && Float.compare(mXOffset, other.mXOffset) == 0;
         }
 
         @Override
@@ -1109,7 +1161,7 @@
             // this needs to match the native VolumeShaper.Operation parceling
             dest.writeInt(mFlags);
             dest.writeInt(mReplaceId);
-            dest.writeFloat(Float.NaN); // xOffset (ignored at Java level)
+            dest.writeFloat(mXOffset);
         }
 
         public static final Parcelable.Creator<VolumeShaper.Operation> CREATOR
@@ -1119,11 +1171,12 @@
                 // this needs to match the native VolumeShaper.Operation parceling
                 final int flags = p.readInt();
                 final int replaceId = p.readInt();
-                final float xOffset = p.readFloat(); // ignored at Java level
+                final float xOffset = p.readFloat();
 
                 return new VolumeShaper.Operation(
                         flags
-                        , replaceId);
+                        , replaceId
+                        , xOffset);
             }
 
             @Override
@@ -1132,9 +1185,10 @@
             }
         };
 
-        private Operation(@Flag int flags, int replaceId) {
+        private Operation(@Flag int flags, int replaceId, float xOffset) {
             mFlags = flags;
             mReplaceId = replaceId;
+            mXOffset = xOffset;
         }
 
         /**
@@ -1146,6 +1200,7 @@
         public static final class Builder {
             int mFlags;
             int mReplaceId;
+            float mXOffset;
 
             /**
              * Constructs a new {@code Builder} with the defaults.
@@ -1153,23 +1208,27 @@
             public Builder() {
                 mFlags = 0;
                 mReplaceId = -1;
+                mXOffset = Float.NaN;
             }
 
             /**
-             * Constructs a new Builder from a given {@code VolumeShaper.Operation}
+             * Constructs a new {@code Builder} from a given {@code VolumeShaper.Operation}
              * @param operation the {@code VolumeShaper.operation} whose data will be
-             *        reused in the new Builder.
+             *        reused in the new {@code Builder}.
              */
             public Builder(@NonNull VolumeShaper.Operation operation) {
                 mReplaceId = operation.mReplaceId;
                 mFlags = operation.mFlags;
+                mXOffset = operation.mXOffset;
             }
 
             /**
-             * Replaces the previous {@code VolumeShaper} specified by id.
-             * It has no other effect if the {@code VolumeShaper} is
-             * already expired.
-             * @param id the id of the previous {@code VolumeShaper}.
+             * Replaces the previous {@code VolumeShaper} specified by {@code id}.
+             *
+             * The {@code VolumeShaper} specified by the {@code id} is removed
+             * if it exists. The configuration should be TYPE_SCALE.
+             *
+             * @param id the {@code id} of the previous {@code VolumeShaper}.
              * @param join if true, match the volume of the previous
              * shaper to the start volume of the new {@code VolumeShaper}.
              * @return the same {@code Builder} instance.
@@ -1194,8 +1253,9 @@
             }
 
             /**
-             * Terminates the VolumeShaper.
-             * Do not call directly, use {@link VolumeShaper#release()}.
+             * Terminates the {@code VolumeShaper}.
+             *
+             * Do not call directly, use {@link VolumeShaper#close()}.
              * @return the same {@code Builder} instance.
              */
             public @NonNull Builder terminate() {
@@ -1214,8 +1274,12 @@
 
             /**
              * Use the id specified in the configuration, creating
-             * VolumeShaper as needed; the configuration should be
+             * {@code VolumeShaper} only as needed; the configuration should be
              * TYPE_SCALE.
+             *
+             * If the {@code VolumeShaper} with the same id already exists
+             * then the operation has no effect.
+             *
              * @return the same {@code Builder} instance.
              */
             public @NonNull Builder createIfNeeded() {
@@ -1224,6 +1288,28 @@
             }
 
             /**
+             * Sets the {@code xOffset} to use for the {@code VolumeShaper}.
+             *
+             * The {@code xOffset} is the position on the volume curve,
+             * and setting takes effect when the {@code VolumeShaper} is used next.
+             *
+             * @param xOffset a value between (or equal to) 0.f and 1.f, or Float.NaN to ignore.
+             * @return the same {@code Builder} instance.
+             * @throws IllegalArgumentException if {@code xOffset} is not between 0.f and 1.f,
+             *         or a Float.NaN.
+             */
+            public @NonNull Builder setXOffset(float xOffset) {
+                if (xOffset < -0.f) {
+                    throw new IllegalArgumentException("Negative xOffset not allowed");
+                } else if (xOffset > 1.f) {
+                    throw new IllegalArgumentException("xOffset > 1.f not allowed");
+                }
+                // Float.NaN passes through
+                mXOffset = xOffset;
+                return this;
+            }
+
+            /**
              * Sets the operation flag.  Do not call this directly but one of the
              * other builder methods.
              *
@@ -1245,7 +1331,7 @@
              * @return a new {@code VolumeShaper.Operation} object
              */
             public @NonNull Operation build() {
-                return new Operation(mFlags, mReplaceId);
+                return new Operation(mFlags, mReplaceId, mXOffset);
             }
         } // Operation.Builder
     } // Operation
@@ -1316,15 +1402,18 @@
 
         /**
          * Gets the volume of the {@link VolumeShaper.State}.
+         * @return linear volume between 0.f and 1.f.
          */
         public float getVolume() {
             return mVolume;
         }
 
         /**
-         * Gets the elapsed ms of the {@link VolumeShaper.State}
+         * Gets the {@code xOffset} position on the normalized curve
+         * of the {@link VolumeShaper.State}.
+         * @return the curve x position between 0.f and 1.f.
          */
-        public double getXOffset() {
+        public float getXOffset() {
             return mXOffset;
         }
     } // State
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index e7da20b..102e02d 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -601,10 +601,12 @@
      * given time frame.
      *
      * @param channelId The ID of the channel to return programs for.
-     * @param startTime The start time used to filter programs. The returned programs should have
-     *            {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this time.
-     * @param endTime The end time used to filter programs. The returned programs should have
-     *            {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time.
+     * @param startTime The start time used to filter programs. The returned programs will have a
+     *            {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than or equal to
+                  {@code startTime}.
+     * @param endTime The end time used to filter programs. The returned programs will have
+     *            {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than or equal to
+     *            {@code endTime}.
      */
     public static Uri buildProgramsUriForChannel(long channelId, long startTime,
             long endTime) {
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 7b5f778..e24124d 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -974,7 +974,7 @@
          * seek to a position earlier than the start position.
          *
          * <p>For playback of a recorded program initiated by {@link #onTimeShiftPlay(Uri)}, the
-         * start position is the time when playback starts. It does not change.
+         * start position should be 0 and does not change.
          *
          * @see #onTimeShiftPlay(Uri)
          * @see #onTimeShiftResume()
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
new file mode 100644
index 0000000..9686ab5
--- /dev/null
+++ b/media/jni/Android.bp
@@ -0,0 +1,83 @@
+cc_library_shared {
+    name: "libmedia_jni",
+
+    srcs: [
+        "android_media_ImageWriter.cpp",
+        "android_media_ImageReader.cpp",
+        "android_media_MediaCrypto.cpp",
+        "android_media_MediaCodec.cpp",
+        "android_media_MediaCodecList.cpp",
+        "android_media_MediaDataSource.cpp",
+        "android_media_MediaDescrambler.cpp",
+        "android_media_MediaDrm.cpp",
+        "android_media_MediaExtractor.cpp",
+        "android_media_MediaHTTPConnection.cpp",
+        "android_media_MediaMetricsJNI.cpp",
+        "android_media_MediaMetadataRetriever.cpp",
+        "android_media_MediaMuxer.cpp",
+        "android_media_MediaPlayer.cpp",
+        "android_media_MediaProfiles.cpp",
+        "android_media_MediaRecorder.cpp",
+        "android_media_MediaScanner.cpp",
+        "android_media_MediaSync.cpp",
+        "android_media_ResampleInputStream.cpp",
+        "android_media_SyncParams.cpp",
+        "android_media_Utils.cpp",
+        "android_mtp_MtpDatabase.cpp",
+        "android_mtp_MtpDevice.cpp",
+        "android_mtp_MtpServer.cpp",
+        "midi/android_media_midi_MidiDevice.cpp",
+    ],
+
+    shared_libs: [
+        "libandroid_runtime",
+        "libnativehelper",
+        "libutils",
+        "libbinder",
+        "libmedia",
+        "libmediametrics",
+        "libmediadrm",
+        "libmidi",
+        "libskia",
+        "libui",
+        "liblog",
+        "libcutils",
+        "libgui",
+        "libstagefright",
+        "libstagefright_foundation",
+        "libcamera_client",
+        "libmtp",
+        "libexif",
+        "libpiex",
+        "libandroidfw",
+    ],
+
+    header_libs: ["libhardware_headers"],
+
+    static_libs: ["libgrallocusage"],
+
+    include_dirs: [
+        "frameworks/base/core/jni",
+        "frameworks/native/include/media/openmax",
+        "system/media/camera/include",
+    ],
+
+    export_include_dirs: ["."],
+
+    export_shared_lib_headers: [
+        "libpiex",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-error=deprecated-declarations",
+        "-Wunused",
+        "-Wunreachable-code",
+    ],
+}
+
+subdirs = [
+    "audioeffect",
+    "soundpool",
+]
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
deleted file mode 100644
index c2ed8cf..0000000
--- a/media/jni/Android.mk
+++ /dev/null
@@ -1,79 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    android_media_ImageWriter.cpp \
-    android_media_ImageReader.cpp \
-    android_media_MediaCrypto.cpp \
-    android_media_MediaCodec.cpp \
-    android_media_MediaCodecList.cpp \
-    android_media_MediaDataSource.cpp \
-    android_media_MediaDescrambler.cpp \
-    android_media_MediaDrm.cpp \
-    android_media_MediaExtractor.cpp \
-    android_media_MediaHTTPConnection.cpp \
-    android_media_MediaMetricsJNI.cpp \
-    android_media_MediaMetadataRetriever.cpp \
-    android_media_MediaMuxer.cpp \
-    android_media_MediaPlayer.cpp \
-    android_media_MediaProfiles.cpp \
-    android_media_MediaRecorder.cpp \
-    android_media_MediaScanner.cpp \
-    android_media_MediaSync.cpp \
-    android_media_ResampleInputStream.cpp \
-    android_media_SyncParams.cpp \
-    android_media_Utils.cpp \
-    android_mtp_MtpDatabase.cpp \
-    android_mtp_MtpDevice.cpp \
-    android_mtp_MtpServer.cpp \
-    midi/android_media_midi_MidiDevice.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
-    libandroid_runtime \
-    libnativehelper \
-    libutils \
-    libbinder \
-    libmedia \
-    libmediametrics \
-    libmediadrm \
-    libmidi \
-    libskia \
-    libui \
-    liblog \
-    libcutils \
-    libgui \
-    libstagefright \
-    libstagefright_foundation \
-    libcamera_client \
-    libmtp \
-    libexif \
-    libpiex \
-    libandroidfw
-
-LOCAL_STATIC_LIBRARIES := \
-    libgrallocusage \
-
-LOCAL_C_INCLUDES += \
-    external/libexif/ \
-    external/piex/ \
-    external/tremor/Tremor \
-    frameworks/base/core/jni \
-    frameworks/base/libs/hwui \
-    frameworks/base/media/native \
-    frameworks/av/media/libmedia \
-    frameworks/av/media/libstagefright \
-    frameworks/av/media/mtp \
-    frameworks/native/include/media/openmax \
-    $(call include-path-for, libhardware)/hardware \
-    $(PV_INCLUDES) \
-    $(JNI_H_INCLUDE)
-
-LOCAL_CFLAGS += -Wall -Werror -Wno-error=deprecated-declarations -Wunused -Wunreachable-code
-
-LOCAL_MODULE:= libmedia_jni
-
-include $(BUILD_SHARED_LIBRARY)
-
-# build libsoundpool.so
-# build libaudioeffect_jni.so
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 163c4b0..52fadfa 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -27,7 +27,6 @@
 
 #include <gui/BufferItemConsumer.h>
 #include <gui/Surface.h>
-#include <camera3.h>
 
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_view_Surface.h>
diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp
index b5ea632..7c424d9 100644
--- a/media/jni/android_media_ImageWriter.cpp
+++ b/media/jni/android_media_ImageWriter.cpp
@@ -25,7 +25,6 @@
 #include <gui/Surface.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_view_Surface.h>
-#include <camera3.h>
 #include <jni.h>
 #include <JNIHelp.h>
 
diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp
index c62d930..458d847 100644
--- a/media/jni/android_media_Utils.cpp
+++ b/media/jni/android_media_Utils.cpp
@@ -17,6 +17,7 @@
 // #define LOG_NDEBUG 0
 #define LOG_TAG "AndroidMediaUtils"
 
+#include <hardware/camera3.h>
 #include <utils/Log.h>
 #include "android_media_Utils.h"
 
diff --git a/media/jni/android_media_Utils.h b/media/jni/android_media_Utils.h
index 39c1554..af2f2d7 100644
--- a/media/jni/android_media_Utils.h
+++ b/media/jni/android_media_Utils.h
@@ -21,7 +21,6 @@
 #include "src/piex.h"
 
 #include <android_runtime/AndroidRuntime.h>
-#include <camera3.h>
 #include <gui/CpuConsumer.h>
 #include <jni.h>
 #include <JNIHelp.h>
diff --git a/media/jni/android_media_VolumeShaper.h b/media/jni/android_media_VolumeShaper.h
index 73498a2..1a13ffa 100644
--- a/media/jni/android_media_VolumeShaper.h
+++ b/media/jni/android_media_VolumeShaper.h
@@ -40,6 +40,7 @@
         jmethodID opConstructId;
         jfieldID  opFlagsId;
         jfieldID  opReplaceIdId;
+        jfieldID  opXOffsetId;
 
         // VolumeShaper.State
         jclass    stClazz;
@@ -74,9 +75,10 @@
             if (opClazz == nullptr) {
                 return;
             }
-            opConstructId = env->GetMethodID(opClazz, "<init>", "(II)V");
+            opConstructId = env->GetMethodID(opClazz, "<init>", "(IIF)V");
             opFlagsId = env->GetFieldID(opClazz, "mFlags", "I");
             opReplaceIdId = env->GetFieldID(opClazz, "mReplaceId", "I");
+            opXOffsetId = env->GetFieldID(opClazz, "mXOffset", "F");
             env->DeleteLocalRef(lclazz);
 
             lclazz = env->FindClass("android/media/VolumeShaper$State");
@@ -179,17 +181,20 @@
         VolumeShaper::Operation::Flag flags =
             (VolumeShaper::Operation::Flag)env->GetIntField(joperation, fields.opFlagsId);
         int replaceId = env->GetIntField(joperation, fields.opReplaceIdId);
+        float xOffset = env->GetFloatField(joperation, fields.opXOffsetId);
 
-        sp<VolumeShaper::Operation> operation = new VolumeShaper::Operation(flags, replaceId);
+        sp<VolumeShaper::Operation> operation =
+                new VolumeShaper::Operation(flags, replaceId, xOffset);
         return operation;
     }
 
     static jobject convertOperationToJobject(
             JNIEnv *env, const fields_t &fields, const sp<VolumeShaper::Operation> &operation) {
         // prepare constructor args
-        jvalue args[2];
+        jvalue args[3];
         args[0].i = (jint)operation->getFlags();
         args[1].i = (jint)operation->getReplaceId();
+        args[2].f = (jfloat)operation->getXOffset();
 
         jobject joperation = env->NewObjectA(fields.opClazz, fields.opConstructId, args);
         return joperation;
diff --git a/media/jni/audioeffect/Android.bp b/media/jni/audioeffect/Android.bp
new file mode 100644
index 0000000..2aca0c1
--- /dev/null
+++ b/media/jni/audioeffect/Android.bp
@@ -0,0 +1,25 @@
+cc_library_shared {
+    name: "libaudioeffect_jni",
+
+    srcs: [
+        "android_media_AudioEffect.cpp",
+        "android_media_Visualizer.cpp",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libcutils",
+        "libutils",
+        "libandroid_runtime",
+        "libnativehelper",
+        "libmedia",
+        "libaudioclient",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wunused",
+        "-Wunreachable-code",
+    ],
+}
diff --git a/media/jni/audioeffect/Android.mk b/media/jni/audioeffect/Android.mk
deleted file mode 100644
index 777636b..0000000
--- a/media/jni/audioeffect/Android.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    android_media_AudioEffect.cpp \
-    android_media_Visualizer.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    liblog \
-    libcutils \
-    libutils \
-    libandroid_runtime \
-    libnativehelper \
-    libmedia \
-    libaudioclient \
-
-LOCAL_MODULE:= libaudioeffect_jni
-
-LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/jni/audioeffect/android_media_AudioEffect.cpp b/media/jni/audioeffect/android_media_AudioEffect.cpp
index 401012f..d4cc3fb 100644
--- a/media/jni/audioeffect/android_media_AudioEffect.cpp
+++ b/media/jni/audioeffect/android_media_AudioEffect.cpp
@@ -86,6 +86,7 @@
     case NO_MEMORY:
         return AUDIOEFFECT_ERROR_NO_MEMORY;
     case DEAD_OBJECT:
+    case FAILED_TRANSACTION: // Hidl crash shows as FAILED_TRANSACTION: -2147483646
         return AUDIOEFFECT_ERROR_DEAD_OBJECT;
     default:
         return AUDIOEFFECT_ERROR;
diff --git a/media/jni/midi/android_media_midi_MidiDevice.cpp b/media/jni/midi/android_media_midi_MidiDevice.cpp
index 3743e4a..4df8436 100644
--- a/media/jni/midi/android_media_midi_MidiDevice.cpp
+++ b/media/jni/midi/android_media_midi_MidiDevice.cpp
@@ -18,7 +18,7 @@
 #define LOG_TAG "Midi-JNI"
 
 #include <android_util_Binder.h>
-#include <midi/midi_internal.h>
+#include <midi_internal.h>
 #include <nativehelper/jni.h>
 #include <utils/Log.h>
 
diff --git a/media/jni/soundpool/Android.bp b/media/jni/soundpool/Android.bp
new file mode 100644
index 0000000..35b7b01
--- /dev/null
+++ b/media/jni/soundpool/Android.bp
@@ -0,0 +1,28 @@
+cc_library_shared {
+    name: "libsoundpool",
+
+    srcs: [
+        "android_media_SoundPool.cpp",
+        "SoundPool.cpp",
+        "SoundPoolThread.cpp",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libcutils",
+        "libutils",
+        "libandroid_runtime",
+        "libnativehelper",
+        "libaudioclient",
+        "libmediandk",
+        "libbinder",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-error=deprecated-declarations",
+        "-Wunused",
+        "-Wunreachable-code",
+    ],
+}
diff --git a/media/jni/soundpool/Android.mk b/media/jni/soundpool/Android.mk
deleted file mode 100644
index 509a59b..0000000
--- a/media/jni/soundpool/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    android_media_SoundPool.cpp \
-    SoundPool.cpp \
-    SoundPoolThread.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    liblog \
-    libcutils \
-    libutils \
-    libandroid_runtime \
-    libnativehelper \
-    libaudioclient \
-    libmediandk \
-    libbinder
-
-LOCAL_MODULE:= libsoundpool
-
-LOCAL_CFLAGS += -Wall -Werror -Wno-error=deprecated-declarations -Wunused -Wunreachable-code
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/native/Android.bp b/media/native/Android.bp
new file mode 100644
index 0000000..b44c296
--- /dev/null
+++ b/media/native/Android.bp
@@ -0,0 +1 @@
+subdirs = ["*"]
diff --git a/media/native/midi/Android.bp b/media/native/midi/Android.bp
index 3500805..11f0dea 100644
--- a/media/native/midi/Android.bp
+++ b/media/native/midi/Android.bp
@@ -12,10 +12,31 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// The headers module is in frameworks/media/native/midi/Android.bp.
-ndk_library {
-    name: "libmidi.ndk",
-    symbol_file: "libmidi.map.txt",
-    first_version: "26",
-//    unversioned_until: "current",
+cc_library_shared {
+    name: "libmidi",
+
+    srcs: [
+        "midi.cpp",
+        ":IMidiDeviceServer.aidl",
+    ],
+
+    aidl: {
+        include_dirs: ["frameworks/base/media/java"],
+        export_aidl_headers: true,
+    },
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-O0",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libbinder",
+        "libutils",
+        "libmedia",
+    ],
+
+    export_include_dirs: ["."],
 }
diff --git a/media/native/midi/Android.mk b/media/native/midi/Android.mk
deleted file mode 100644
index dbc5eed..0000000
--- a/media/native/midi/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-	../../java/android/media/midi/IMidiDeviceServer.aidl \
-	midi.cpp
-
-LOCAL_AIDL_INCLUDES := \
-	$(FRAMEWORKS_BASE_JAVA_SRC_DIRS) \
-	frameworks/native/aidl/binder
-
-LOCAL_CFLAGS += -Wall -Werror -O0
-
-LOCAL_MODULE := libmidi
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SHARED_LIBRARIES := liblog libbinder libutils libmedia
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/obex/javax/obex/ApplicationParameter.java b/obex/javax/obex/ApplicationParameter.java
index a62210f..16770a1a 100644
--- a/obex/javax/obex/ApplicationParameter.java
+++ b/obex/javax/obex/ApplicationParameter.java
@@ -55,7 +55,7 @@
 
         public static final byte LISTSTARTOFFSET_TAGID = 0x05;
 
-        public static final byte FILTER_TAGID = 0x06;
+        public static final byte PROPERTY_SELECTOR_TAGID = 0x06;
 
         public static final byte FORMAT_TAGID = 0x07;
 
@@ -64,6 +64,20 @@
 
         // only used in "mch" in response
         public static final byte NEWMISSEDCALLS_TAGID = 0x09;
+
+        public static final byte SUPPORTEDFEATURE_TAGID = 0x10;
+
+        public static final byte PRIMARYVERSIONCOUNTER_TAGID = 0x0A;
+
+        public static final byte SECONDARYVERSIONCOUNTER_TAGID = 0x0B;
+
+        public static final byte VCARDSELECTOR_TAGID = 0x0C;
+
+        public static final byte DATABASEIDENTIFIER_TAGID = 0x0D;
+
+        public static final byte VCARDSELECTOROPERATOR_TAGID = 0x0E;
+
+        public static final byte RESET_NEW_MISSED_CALLS_TAGID = 0x0F;
     }
 
     public static class TRIPLET_VALUE {
@@ -99,13 +113,27 @@
 
         public static final byte LISTSTARTOFFSET_LENGTH = 2;
 
-        public static final byte FILTER_LENGTH = 8;
+        public static final byte PROPERTY_SELECTOR_LENGTH = 8;
 
         public static final byte FORMAT_LENGTH = 1;
 
         public static final byte PHONEBOOKSIZE_LENGTH = 2;
 
         public static final byte NEWMISSEDCALLS_LENGTH = 1;
+
+        public static final byte SUPPORTEDFEATURE_LENGTH = 4;
+
+        public static final byte PRIMARYVERSIONCOUNTER_LENGTH = 16;
+
+        public static final byte SECONDARYVERSIONCOUNTER_LENGTH = 16;
+
+        public static final byte VCARDSELECTOR_LENGTH = 8;
+
+        public static final byte DATABASEIDENTIFIER_LENGTH = 16;
+
+        public static final byte VCARDSELECTOROPERATOR_LENGTH = 1;
+
+        public static final byte RESETNEWMISSEDCALLS_LENGTH = 1;
     }
 
     public ApplicationParameter() {
diff --git a/packages/MtpDocumentsProvider/AndroidManifest.xml b/packages/MtpDocumentsProvider/AndroidManifest.xml
index 843b313..8d79f62 100644
--- a/packages/MtpDocumentsProvider/AndroidManifest.xml
+++ b/packages/MtpDocumentsProvider/AndroidManifest.xml
@@ -22,7 +22,6 @@
                   android:label="@string/downloads_app_label"
                   android:icon="@mipmap/ic_launcher_download"
                   android:theme="@android:style/Theme.NoDisplay"
-                  android:screenOrientation="locked"
                   android:excludeFromRecents="true">
             <intent-filter>
                 <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/ServiceIntentSender.java b/packages/MtpDocumentsProvider/src/com/android/mtp/ServiceIntentSender.java
index c5292b8..629f6df 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/ServiceIntentSender.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/ServiceIntentSender.java
@@ -18,19 +18,38 @@
 
 import android.annotation.NonNull;
 import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
 
 /**
  * Sends intent to MtpDocumentsService.
  */
 class ServiceIntentSender {
-    private Context mContext;
+    private final static String CHANNEL_ID = "device_notification_channel";
+    private final Context mContext;
 
     ServiceIntentSender(Context context) {
         mContext = context;
+
+        // Create notification channel.
+        final NotificationChannel mChannel = new NotificationChannel(
+                CHANNEL_ID,
+                context.getResources().getString(
+                        com.android.internal.R.string.default_notification_channel_label),
+                NotificationManager.IMPORTANCE_LOW);
+        final NotificationManager notificationManager =
+                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+        notificationManager.createNotificationChannel(mChannel);
+    }
+
+    @VisibleForTesting
+    protected ServiceIntentSender() {
+        mContext = null;
     }
 
     /**
@@ -60,12 +79,11 @@
         final String title = context.getResources().getString(
                 R.string.accessing_notification_title,
                 device.name);
-        return new Notification.Builder(context)
+        return new Notification.Builder(context, CHANNEL_ID)
                 .setLocalOnly(true)
                 .setContentTitle(title)
                 .setSmallIcon(com.android.internal.R.drawable.stat_sys_data_usb)
                 .setCategory(Notification.CATEGORY_SYSTEM)
-                .setPriority(Notification.PRIORITY_LOW)
                 .setFlag(Notification.FLAG_NO_CLEAR, true)
                 .build();
     }
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestServiceIntentSender.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestServiceIntentSender.java
index ed2dc38..17b3086 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestServiceIntentSender.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestServiceIntentSender.java
@@ -17,10 +17,6 @@
 package com.android.mtp;
 
 class TestServiceIntentSender extends ServiceIntentSender {
-    TestServiceIntentSender() {
-        super(null);
-    }
-
     @Override
     void sendUpdateNotificationIntent(MtpDeviceRecord[] record) {}
 }
diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml
index 0647b4f..6c322ed 100644
--- a/packages/SettingsLib/res/values-da/arrays.xml
+++ b/packages/SettingsLib/res/values-da/arrays.xml
@@ -49,9 +49,9 @@
     <item msgid="1805837518286731242">"Undgår midlertidigt dårlig forbindelse"</item>
   </string-array>
   <string-array name="hdcp_checking_titles">
-    <item msgid="441827799230089869">"Kontrollér aldrig"</item>
-    <item msgid="6042769699089883931">"Kontrollér kun for DRM-indhold"</item>
-    <item msgid="9174900380056846820">"Kontrollér altid"</item>
+    <item msgid="441827799230089869">"Tjek aldrig"</item>
+    <item msgid="6042769699089883931">"Tjek kun for DRM-indhold"</item>
+    <item msgid="9174900380056846820">"Tjek altid"</item>
   </string-array>
   <string-array name="hdcp_checking_summaries">
     <item msgid="505558545611516707">"Brug aldrig HDCP-kontrol"</item>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 0447c52..aa0becf 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -210,7 +210,7 @@
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"Vil du tillade udviklingsindstillinger?"</string>
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Disse indstillinger er kun beregnet til brug i forbindelse med udvikling. De kan forårsage, at din enhed og dens applikationer går ned eller ikke fungerer korrekt."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verificer apps via USB"</string>
-    <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Kontrollér apps, der er installeret via ADB/ADT, for skadelig adfærd."</string>
+    <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Tjek apps, der er installeret via ADB/ADT, for skadelig adfærd."</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Deaktiverer funktionen til absolut lydstyrke via Bluetooth i tilfælde af problemer med lydstyrken på eksterne enheder, f.eks. uacceptabel høj lyd eller manglende kontrol."</string>
     <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"Tillad, at ringetoner på telefonen kan afspilles i Bluetooth-headset"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Lokal terminal"</string>
@@ -298,7 +298,7 @@
     <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Inaktiv. Tryk for at skifte."</string>
     <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktiv. Tryk for at skifte."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Kørende tjenester"</string>
-    <string name="runningservices_settings_summary" msgid="854608995821032748">"Vis og kontrollér kørende tjenester"</string>
+    <string name="runningservices_settings_summary" msgid="854608995821032748">"Vis og administrer kørende tjenester"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-implementering"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Konfigurer WebView-implementering"</string>
     <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"Dette valg er ikke længere gyldigt. Prøv igen."</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 3250d03..399199d 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -109,7 +109,7 @@
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"Ton"</string>
     <string name="tts_default_pitch_summary" msgid="1944885882882650009">"Afecta ao ton da voz sintetizada"</string>
     <string name="tts_default_lang_title" msgid="8018087612299820556">"Idioma"</string>
-    <string name="tts_lang_use_system" msgid="2679252467416513208">"Utilizar idioma do sistema"</string>
+    <string name="tts_lang_use_system" msgid="2679252467416513208">"Utiliza o idioma do sistema"</string>
     <string name="tts_lang_not_selected" msgid="7395787019276734765">"Idioma non seleccionado"</string>
     <string name="tts_default_lang_summary" msgid="5219362163902707785">"Define a voz específica do idioma para o texto falado"</string>
     <string name="tts_play_example_title" msgid="7094780383253097230">"Escoitar un exemplo"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 41a116e..3ed642d 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -294,7 +294,7 @@
     <item msgid="8280754435979370728">"നമ്മൾ കാണുന്നത് പോലെയുള്ള സ്വാഭാവിക വർണ്ണങ്ങൾ"</item>
     <item msgid="5363960654009010371">"ഡിജിറ്റൽ ഉള്ളടക്കത്തിനായി വർണ്ണങ്ങൾ ഒപ്റ്റിമൈസ് ചെയ്തു"</item>
   </string-array>
-    <string name="inactive_apps_title" msgid="1317817863508274533">"നിഷ്‌ക്രിയ ആപ്പ്‌സ്"</string>
+    <string name="inactive_apps_title" msgid="1317817863508274533">"നിഷ്‌ക്രിയ ആപ്പുകൾ"</string>
     <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"നിഷ്‌ക്രിയം. മാറ്റുന്നതിനു ടാപ്പുചെയ്യുക."</string>
     <string name="inactive_app_active_summary" msgid="4174921824958516106">"സജീവം. മാറ്റുന്നതിന് ടാപ്പുചെയ്യുക."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"പ്രവർത്തിക്കുന്ന സേവനങ്ങൾ"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index 24ede16..7268d00 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -19,6 +19,8 @@
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothCodecConfig;
+import android.bluetooth.BluetoothCodecStatus;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
 import android.bluetooth.BluetoothUuid;
@@ -26,16 +28,22 @@
 import android.os.ParcelUuid;
 import android.util.Log;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.R;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
-public final class A2dpProfile implements LocalBluetoothProfile {
+public class A2dpProfile implements LocalBluetoothProfile {
     private static final String TAG = "A2dpProfile";
     private static boolean V = false;
 
+    private Context mContext;
+
     private BluetoothA2dp mService;
+    BluetoothA2dpWrapper.Factory mWrapperFactory;
+    private BluetoothA2dpWrapper mServiceWrapper;
     private boolean mIsProfileReady;
 
     private final LocalBluetoothAdapter mLocalAdapter;
@@ -59,6 +67,7 @@
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
             if (V) Log.d(TAG,"Bluetooth service connected");
             mService = (BluetoothA2dp) proxy;
+            mServiceWrapper = mWrapperFactory.getInstance(mService);
             // We just bound to the service, so refresh the UI for any connected A2DP devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
             while (!deviceList.isEmpty()) {
@@ -88,13 +97,20 @@
     A2dpProfile(Context context, LocalBluetoothAdapter adapter,
             CachedBluetoothDeviceManager deviceManager,
             LocalBluetoothProfileManager profileManager) {
+        mContext = context;
         mLocalAdapter = adapter;
         mDeviceManager = deviceManager;
         mProfileManager = profileManager;
+        mWrapperFactory = new BluetoothA2dpWrapperImpl.Factory();
         mLocalAdapter.getProfileProxy(context, new A2dpServiceListener(),
                 BluetoothProfile.A2DP);
     }
 
+    @VisibleForTesting
+    void setWrapperFactory(BluetoothA2dpWrapper.Factory factory) {
+        mWrapperFactory = factory;
+    }
+
     public boolean isConnectable() {
         return true;
     }
@@ -173,6 +189,72 @@
         return false;
     }
 
+    public boolean supportsHighQualityAudio(BluetoothDevice device) {
+        int support = mServiceWrapper.supportsOptionalCodecs(device);
+        return support == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED;
+    }
+
+    public boolean isHighQualityAudioEnabled(BluetoothDevice device) {
+        int enabled = mServiceWrapper.getOptionalCodecsEnabled(device);
+        if (enabled != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN) {
+            return enabled == BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED;
+        } else if (getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED &&
+                supportsHighQualityAudio(device)) {
+            // Since we don't have a stored preference and the device isn't connected, just return
+            // true since the default behavior when the device gets connected in the future would be
+            // to have optional codecs enabled.
+            return true;
+        }
+        BluetoothCodecConfig codecConfig = null;
+        if (mServiceWrapper.getCodecStatus() != null) {
+            codecConfig = mServiceWrapper.getCodecStatus().getCodecConfig();
+        }
+        if (codecConfig != null)  {
+            return !codecConfig.isMandatoryCodec();
+        } else {
+            return false;
+        }
+    }
+
+    public void setHighQualityAudioEnabled(BluetoothDevice device, boolean enabled) {
+        int prefValue = enabled
+                ? BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED
+                : BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED;
+        mServiceWrapper.setOptionalCodecsEnabled(device, prefValue);
+        if (getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED) {
+            return;
+        }
+        if (enabled) {
+            mService.enableOptionalCodecs();
+        } else {
+            mService.disableOptionalCodecs();
+        }
+    }
+
+    public String getHighQualityAudioOptionLabel(BluetoothDevice device) {
+        int unknownCodecId = R.string.bluetooth_profile_a2dp_high_quality_unknown_codec;
+        if (!supportsHighQualityAudio(device) ||
+                getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED) {
+            return mContext.getString(unknownCodecId);
+        }
+        // We want to get the highest priority codec, since that's the one that will be used with
+        // this device, and see if it is high-quality (ie non-mandatory).
+        BluetoothCodecConfig[] selectable = null;
+        if (mServiceWrapper.getCodecStatus() != null) {
+            selectable = mServiceWrapper.getCodecStatus().getCodecsSelectableCapabilities();
+            // To get the highest priority, we sort in reverse.
+            Arrays.sort(selectable,
+                    (a, b) -> {
+                        return b.getCodecPriority() - a.getCodecPriority();
+                    });
+        }
+        if (selectable == null || selectable.length < 1 || selectable[0].isMandatoryCodec()) {
+            return mContext.getString(unknownCodecId);
+        }
+        return mContext.getString(R.string.bluetooth_profile_a2dp_high_quality,
+                selectable[0].getCodecName());
+    }
+
     public String toString() {
         return NAME;
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothA2dpWrapper.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothA2dpWrapper.java
new file mode 100644
index 0000000..aa3e835
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothA2dpWrapper.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.settingslib.bluetooth;
+
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothCodecStatus;
+import android.bluetooth.BluetoothDevice;
+
+/**
+ * This interface replicates some methods of android.bluetooth.BluetoothA2dp that are new and not
+ * yet available in our current version of  Robolectric. It provides a thin wrapper to call the real
+ * methods in production and a mock in tests.
+ */
+public interface BluetoothA2dpWrapper {
+
+    static interface Factory {
+        BluetoothA2dpWrapper getInstance(BluetoothA2dp service);
+    }
+
+    /**
+     * @return the real {@code BluetoothA2dp} object
+     */
+    BluetoothA2dp getService();
+
+    /**
+     * Wraps {@code BluetoothA2dp.getCodecStatus}
+     */
+    public BluetoothCodecStatus getCodecStatus();
+
+    /**
+     * Wraps {@code BluetoothA2dp.supportsOptionalCodecs}
+     */
+    int supportsOptionalCodecs(BluetoothDevice device);
+
+    /**
+     * Wraps {@code BluetoothA2dp.getOptionalCodecsEnabled}
+     */
+    int getOptionalCodecsEnabled(BluetoothDevice device);
+
+    /**
+     * Wraps {@code BluetoothA2dp.setOptionalCodecsEnabled}
+     */
+    void setOptionalCodecsEnabled(BluetoothDevice device, int value);
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothA2dpWrapperImpl.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothA2dpWrapperImpl.java
new file mode 100644
index 0000000..14fa796
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothA2dpWrapperImpl.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.settingslib.bluetooth;
+
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothCodecStatus;
+import android.bluetooth.BluetoothDevice;
+
+public class BluetoothA2dpWrapperImpl implements BluetoothA2dpWrapper {
+
+    public static class Factory implements BluetoothA2dpWrapper.Factory {
+        @Override
+        public BluetoothA2dpWrapper getInstance(BluetoothA2dp service) {
+            return new BluetoothA2dpWrapperImpl(service);
+        }
+    }
+
+    private BluetoothA2dp mService;
+
+    public BluetoothA2dpWrapperImpl(BluetoothA2dp service) {
+        mService = service;
+    }
+
+    @Override
+    public BluetoothA2dp getService() {
+        return mService;
+    }
+
+    @Override
+    public BluetoothCodecStatus getCodecStatus() {
+        return mService.getCodecStatus();
+    }
+
+    @Override
+    public int supportsOptionalCodecs(BluetoothDevice device) {
+        return mService.supportsOptionalCodecs(device);
+    }
+
+    @Override
+    public int getOptionalCodecsEnabled(BluetoothDevice device) {
+        return mService.getOptionalCodecsEnabled(device);
+    }
+
+    @Override
+    public void setOptionalCodecsEnabled(BluetoothDevice device, int value) {
+        mService.setOptionalCodecsEnabled(device, value);
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 5a9a749..0750dc7 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -42,7 +42,7 @@
  * LocalBluetoothProfileManager provides access to the LocalBluetoothProfile
  * objects for the available Bluetooth profiles.
  */
-public final class LocalBluetoothProfileManager {
+public class LocalBluetoothProfileManager {
     private static final String TAG = "LocalBluetoothProfileManager";
     private static final boolean DEBUG = Utils.D;
     /** Singleton instance. */
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
index 3a2397f..bb525c8 100755
--- a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
@@ -26,6 +26,8 @@
 import android.graphics.ColorFilter;
 import android.graphics.Paint;
 import android.graphics.Path;
+import android.graphics.Path.Direction;
+import android.graphics.Path.FillType;
 import android.graphics.RectF;
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
@@ -36,8 +38,9 @@
 
 public class BatteryMeterDrawableBase extends Drawable {
 
-    private static final float ASPECT_RATIO = 9.5f / 14.5f;
+    private static final float ASPECT_RATIO = .58f;
     public static final String TAG = BatteryMeterDrawableBase.class.getSimpleName();
+    private static final float RADIUS_RATIO = 1.75f / 17f;
 
     protected final Context mContext;
     protected final Paint mFramePaint;
@@ -263,28 +266,20 @@
         final int width = (int) (ASPECT_RATIO * mHeight);
         int px = (mWidth - width) / 2;
 
-        final int buttonHeight = (int) (height * mButtonHeightFraction);
+        final int buttonHeight = Math.round(height * mButtonHeightFraction);
 
         mFrame.set(0, 0, width, height);
         mFrame.offset(px, 0);
 
         // button-frame: area above the battery body
         mButtonFrame.set(
-                mFrame.left + Math.round(width * 0.25f),
+                mFrame.left + Math.round(width * 0.3f),
                 mFrame.top,
-                mFrame.right - Math.round(width * 0.25f),
+                mFrame.right - Math.round(width * 0.3f),
                 mFrame.top + buttonHeight);
 
-        mButtonFrame.top += mSubpixelSmoothingLeft;
-        mButtonFrame.left += mSubpixelSmoothingLeft;
-        mButtonFrame.right -= mSubpixelSmoothingRight;
-
         // frame: battery body area
         mFrame.top += buttonHeight;
-        mFrame.left += mSubpixelSmoothingLeft;
-        mFrame.top += mSubpixelSmoothingLeft;
-        mFrame.right -= mSubpixelSmoothingRight;
-        mFrame.bottom -= mSubpixelSmoothingRight;
 
         // set the battery charging color
         mBatteryPaint.setColor(mCharging ? mChargeColor : getColorForLevel(level));
@@ -300,15 +295,10 @@
 
         // define the battery shape
         mShapePath.reset();
-        mShapePath.moveTo(mButtonFrame.left, mButtonFrame.top);
-        mShapePath.lineTo(mButtonFrame.right, mButtonFrame.top);
-        mShapePath.lineTo(mButtonFrame.right, mFrame.top);
-        mShapePath.lineTo(mFrame.right, mFrame.top);
-        mShapePath.lineTo(mFrame.right, mFrame.bottom);
-        mShapePath.lineTo(mFrame.left, mFrame.bottom);
-        mShapePath.lineTo(mFrame.left, mFrame.top);
-        mShapePath.lineTo(mButtonFrame.left, mFrame.top);
-        mShapePath.lineTo(mButtonFrame.left, mButtonFrame.top);
+        final float radius = RADIUS_RATIO * (mFrame.height() + buttonHeight);
+        mShapePath.setFillType(FillType.WINDING);
+        mShapePath.addRoundRect(mFrame, radius, radius, Direction.CW);
+        mShapePath.addRect(mButtonFrame, Direction.CW);
 
         if (mCharging) {
             // define the bolt shape
diff --git a/packages/SettingsLib/tests/robotests/src/android/bluetooth/BluetoothCodecConfig.java b/packages/SettingsLib/tests/robotests/src/android/bluetooth/BluetoothCodecConfig.java
new file mode 100644
index 0000000..656ab86
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/android/bluetooth/BluetoothCodecConfig.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package android.bluetooth;
+
+/**
+ * A placeholder class to prevent ClassNotFound exceptions caused by lack of visibility.
+ */
+public class BluetoothCodecConfig {
+    public boolean isMandatoryCodec() { return true; }
+    public String getCodecName() { return null;}
+}
diff --git a/packages/SettingsLib/tests/robotests/src/android/bluetooth/BluetoothCodecStatus.java b/packages/SettingsLib/tests/robotests/src/android/bluetooth/BluetoothCodecStatus.java
new file mode 100644
index 0000000..919ec3f
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/android/bluetooth/BluetoothCodecStatus.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package android.bluetooth;
+
+/**
+ * A placeholder class to prevent ClassNotFound exceptions caused by lack of visibility.
+ */
+public class BluetoothCodecStatus {
+    public BluetoothCodecConfig getCodecConfig() { return null; }
+    public BluetoothCodecConfig[] getCodecsSelectableCapabilities() { return null; }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
new file mode 100644
index 0000000..07a0e11
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 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.
+ */
+package com.android.settingslib.bluetooth;
+
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothCodecConfig;
+import android.bluetooth.BluetoothCodecStatus;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+
+import com.android.settingslib.R;
+import com.android.settingslib.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class A2dpProfileTest {
+
+    @Mock Context mContext;
+    @Mock LocalBluetoothAdapter mAdapter;
+    @Mock CachedBluetoothDeviceManager mDeviceManager;
+    @Mock LocalBluetoothProfileManager mProfileManager;
+    @Mock BluetoothDevice mDevice;
+    @Mock BluetoothA2dp mBluetoothA2dp;
+    @Mock BluetoothA2dpWrapper mBluetoothA2dpWrapper;
+    BluetoothProfile.ServiceListener mServiceListener;
+
+    A2dpProfile mProfile;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        // Capture the A2dpServiceListener our A2dpProfile will pass during its constructor, so that
+        // we can call its onServiceConnected method and get it to use our mock BluetoothA2dp
+        // object.
+        doAnswer((invocation) -> {
+            mServiceListener = (BluetoothProfile.ServiceListener) invocation.getArguments()[1];
+            return null;
+        }).when(mAdapter).getProfileProxy(any(Context.class), any(), eq(BluetoothProfile.A2DP));
+
+        mProfile = new A2dpProfile(mContext, mAdapter, mDeviceManager, mProfileManager);
+        mProfile.setWrapperFactory((service) -> { return mBluetoothA2dpWrapper; });
+        mServiceListener.onServiceConnected(BluetoothProfile.A2DP, mBluetoothA2dp);
+    }
+
+    @Test
+    public void supportsHighQualityAudio() {
+        when(mBluetoothA2dpWrapper.supportsOptionalCodecs(any())).thenReturn(
+                BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
+        assertThat(mProfile.supportsHighQualityAudio(mDevice)).isTrue();
+
+        when(mBluetoothA2dpWrapper.supportsOptionalCodecs(any())).thenReturn(
+                BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
+        assertThat(mProfile.supportsHighQualityAudio(mDevice)).isFalse();
+
+        when(mBluetoothA2dpWrapper.supportsOptionalCodecs(any())).thenReturn(
+                BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN);
+        assertThat(mProfile.supportsHighQualityAudio(mDevice)).isFalse();
+    }
+
+    @Test
+    public void isHighQualityAudioEnabled() {
+        when(mBluetoothA2dpWrapper.getOptionalCodecsEnabled(any())).thenReturn(
+                BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED);
+        assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isTrue();
+
+        when(mBluetoothA2dpWrapper.getOptionalCodecsEnabled(any())).thenReturn(
+                BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED);
+        assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isFalse();
+
+        // If we don't have a stored pref for whether optional codecs should be enabled or not,
+        // then isHighQualityAudioEnabled() should return true or false based on whether optional
+        // codecs are supported. If the device is connected then we should ask it directly, but if
+        // the device isn't connected then rely on the stored pref about such support.
+        when(mBluetoothA2dpWrapper.getOptionalCodecsEnabled(any())).thenReturn(
+                BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN);
+        when(mBluetoothA2dp.getConnectionState(any())).thenReturn(
+                BluetoothProfile.STATE_DISCONNECTED);
+
+        when(mBluetoothA2dpWrapper.supportsOptionalCodecs(any())).thenReturn(
+                BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
+        assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isFalse();
+
+        when(mBluetoothA2dpWrapper.supportsOptionalCodecs(any())).thenReturn(
+                BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
+        assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isTrue();
+
+        when(mBluetoothA2dp.getConnectionState(any())).thenReturn(
+                BluetoothProfile.STATE_CONNECTED);
+        BluetoothCodecStatus status = mock(BluetoothCodecStatus.class);
+        when(mBluetoothA2dpWrapper.getCodecStatus()).thenReturn(status);
+        BluetoothCodecConfig config = mock(BluetoothCodecConfig.class);
+        when(status.getCodecConfig()).thenReturn(config);
+        when(config.isMandatoryCodec()).thenReturn(false);
+        assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isTrue();
+        when(config.isMandatoryCodec()).thenReturn(true);
+        assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isFalse();
+    }
+
+    // Strings to use in fake resource lookups.
+    private static String KNOWN_CODEC_LABEL = "Use high quality audio: %1$s";
+    private static String UNKNOWN_CODEC_LABEL = "Use high quality audio";
+
+    /**
+     * Helper for setting up several tests of getHighQualityAudioOptionLabel
+     */
+    private void setupLabelTest() {
+        // SettingsLib doesn't have string resource lookup working for robotests, so fake our own
+        // string loading.
+        when(mContext.getString(eq(R.string.bluetooth_profile_a2dp_high_quality),
+                any(String.class))).thenAnswer((invocation) -> {
+            return String.format(KNOWN_CODEC_LABEL, invocation.getArguments()[1]);
+        });
+        when(mContext.getString(eq(R.string.bluetooth_profile_a2dp_high_quality_unknown_codec)))
+                .thenReturn(UNKNOWN_CODEC_LABEL);
+
+        // Most tests want to simulate optional codecs being supported by the device, so do that
+        // by default here.
+        when(mBluetoothA2dpWrapper.supportsOptionalCodecs(any())).thenReturn(
+                BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
+    }
+
+    @Test
+    public void getLableCodecsNotSupported() {
+        setupLabelTest();
+        when(mBluetoothA2dpWrapper.supportsOptionalCodecs(any())).thenReturn(
+                BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
+        assertThat(mProfile.getHighQualityAudioOptionLabel(mDevice)).isEqualTo(UNKNOWN_CODEC_LABEL);
+    }
+
+    @Test
+    public void getLabelDeviceDisconnected() {
+        setupLabelTest();
+        when(mBluetoothA2dp.getConnectionState(any())).thenReturn(
+                BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mProfile.getHighQualityAudioOptionLabel(mDevice)).isEqualTo(UNKNOWN_CODEC_LABEL);
+    }
+
+    @Test
+    public void getLabelDeviceConnectedButNotHighQualityCodec() {
+        setupLabelTest();
+        when(mBluetoothA2dp.getConnectionState(any())).thenReturn(
+                BluetoothProfile.STATE_CONNECTED);
+        BluetoothCodecStatus status = mock(BluetoothCodecStatus.class);
+        BluetoothCodecConfig config = mock(BluetoothCodecConfig.class);
+        BluetoothCodecConfig[] configs = {config};
+        when(mBluetoothA2dpWrapper.getCodecStatus()).thenReturn(status);
+        when(status.getCodecsSelectableCapabilities()).thenReturn(configs);
+
+        when(config.isMandatoryCodec()).thenReturn(true);
+        assertThat(mProfile.getHighQualityAudioOptionLabel(mDevice)).isEqualTo(UNKNOWN_CODEC_LABEL);
+    }
+
+    @Test
+    public void getLabelDeviceConnectedWithHighQualityCodec() {
+        setupLabelTest();
+        when(mBluetoothA2dp.getConnectionState(any())).thenReturn(
+                BluetoothProfile.STATE_CONNECTED);
+        BluetoothCodecStatus status = mock(BluetoothCodecStatus.class);
+        BluetoothCodecConfig config = mock(BluetoothCodecConfig.class);
+        BluetoothCodecConfig[] configs = {config};
+        when(mBluetoothA2dpWrapper.getCodecStatus()).thenReturn(status);
+        when(status.getCodecsSelectableCapabilities()).thenReturn(configs);
+
+        when(config.isMandatoryCodec()).thenReturn(false);
+        when(config.getCodecName()).thenReturn("PiedPiper");
+        assertThat(mProfile.getHighQualityAudioOptionLabel(mDevice)).isEqualTo(
+                String.format(KNOWN_CODEC_LABEL, config.getCodecName()));
+    }
+}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index d43b740..f57f48f 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -192,6 +192,9 @@
     <!-- to access ResolverRankerServices -->
     <uses-permission android:name="android.permission.BIND_RESOLVER_RANKER_SERVICE" />
 
+    <!-- to access instant apps -->
+    <uses-permission android:name="android.permission.ACCESS_INSTANT_APPS" />
+
     <application
         android:name=".SystemUIApplication"
         android:persistent="true"
diff --git a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/drawable/GradientDrawable.java b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/drawable/GradientDrawable.java
index e75d95a..38e16f3 100644
--- a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/drawable/GradientDrawable.java
+++ b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/drawable/GradientDrawable.java
@@ -157,7 +157,10 @@
     }
 
     private void buildPaints() {
-        final Rect bounds = mWindowBounds;
+        Rect bounds = mWindowBounds;
+        if (bounds.width() == 0) {
+            return;
+        }
 
         float w = bounds.width();
         float h = bounds.height();
@@ -177,7 +180,10 @@
 
     @Override
     public void draw(@NonNull Canvas canvas) {
-        final Rect bounds = mWindowBounds;
+        Rect bounds = mWindowBounds;
+        if (bounds.width() == 0) {
+            throw new IllegalStateException("You need to call setScreenSize before drawing.");
+        }
 
         // Splat each gradient
         float w = bounds.width();
diff --git a/packages/SystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml b/packages/SystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml
index b131c38..99ee3b1 100644
--- a/packages/SystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml
+++ b/packages/SystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2016 The Android Open Source Project
+Copyright (C) 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.
@@ -16,10 +16,13 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="17dp"
         android:height="17dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M14.0,24.0l-4.0,-4.0l-4.0,4.0l4.0,4.0L14.0,24.0zM35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6zM38.0,20.0l-4.0,4.0l4.0,4.0l4.0,-4.0L38.0,20.0z"/>
+        android:viewportWidth="18.0"
+        android:viewportHeight="18.0">
+    <group
+        android:translateY="0.5"
+        android:translateX="0.5" >
+        <path
+            android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 51eefb6..029d16e 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -48,7 +48,6 @@
         android:layout_height="match_parent"
         android:importantForAccessibility="no"
         sysui:ignoreRightInset="true"
-        sysui:scrimColor="@color/scrim_behind_color"
         />
 
     <com.android.systemui.statusbar.AlphaOptimizedView
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 7a93f8f..bb4f2d8 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Af"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Met kragkennisgewingkontroles kan jy \'n belangrikheidvlak van 0 tot 5 vir \'n program se kennisgewings stel. \n\n"<b>"Vlak 5"</b>" \n- Wys aan die bokant van die kennisgewinglys \n- Laat volskermonderbreking toe \n- Wys altyd opspringkennisgewings \n\n"<b>"Vlak 4"</b>" \n- Verhoed volskermonderbreking \n- Wys altyd opspringkennisgewings \n\n"<b>"Vlak 3"</b>" \n- Verhoed volskermonderbreking \n- Verhoed opspringkennisgewings \n\n"<b>"Vlak 2"</b>" \n- Verhoed volskermonderbreking \n- Verhoed opspringkennisgewings \n- Moet nooit \'n klank maak of vibreer nie \n\n"<b>"Vlak 1"</b>" \n- Verhoed volskermonderbreking \n- Verhoed opspringkennisgewings \n- Moet nooit \'n klank maak of vibreer nie \n- Versteek van sluitskerm en statusbalk \n- Wys aan die onderkant van die kennisgewinglys \n\n"<b>"Vlak 0"</b>" \n- Blokkeer alle kennisgewings van die program af"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Kennisgewings"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Jy sal nie meer hierdie kennisgewings kry nie."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Jy sal nie meer hierdie kennisgewings kry nie"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> kennisgewingkategorieë"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Hierdie program het nie kennisgewingkategorieë nie"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-af/strings_tv.xml b/packages/SystemUI/res/values-af/strings_tv.xml
index 3582af1..8a1e6c9 100644
--- a/packages/SystemUI/res/values-af/strings_tv.xml
+++ b/packages/SystemUI/res/values-af/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Beeld-in-beeld"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Titellose program)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Maak PIP toe"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Volskerm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index afef464..b037336 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ጠፍቷል"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"በኃይል ማሳወቂያ መቆጣጠሪያዎች አማካኝነት የአንድ መተግበሪያ ማሳወቂያዎች የአስፈላጊነት ደረጃ ከ0 እስከ 5 ድረስ ማዘጋጀት ይችላሉ። \n\n"<b>"ደረጃ 5"</b>" \n- በማሳወቂያ ዝርዝሩ አናት ላይ አሳይ \n- የሙሉ ማያ ገጽ ማቋረጥን ፍቀድ \n- ሁልጊዜ አጮልቀው ይመልከቱ \n\n"<b>"ደረጃ 4"</b>" \n- የሙሉ ማያ ገጽ ማቋረጥን ከልክል \n- ሁልጊዜ አጮልቀው ይመልከቱ \n\n"<b>"ደረጃ 3"</b>" \n- የሙሉ ማያ ገጽ ማቋረጥን ከልክል \n- በፍጹም አጮልቀው አይምልከቱ \n\n"<b>"ደረጃ 2"</b>" \n- የሙሉ ማያ ገጽ ማቋረጥን ይከልክሉ \n- በፍጹም አጮልቀው አይመልከቱ \n- ድምፅ እና ንዝረትን በፍጹም አይኑር \n\n"<b>"ደረጃ 1"</b>" \n- የሙሉ ማያ ገጽ ማቋረጥን ይከልክሉ \n- በፍጹም አጮልቀው አይመልከቱ \n- ድምፅ ወይም ንዝረትን በፍጹም አያደርጉ \n- ከመቆለፊያ ገጽ እና የሁኔታ አሞሌ ይደብቁ \n- በማሳወቂያ ዝርዝር ግርጌ ላይ አሳይ \n\n"<b>"ደረጃ 0"</b>" \n- ሁሉንም የመተግበሪያው ማሳወቂያዎች ያግዱ"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"ማሳወቂያዎች"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"እነዚህን ማሳወቂያዎች ከእንግዲህ አያግኙዋቸውም።"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"እነዚህን ማሳወቂያዎች ከእንግዲህ አያገኟቸውም"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> የማሳወቂያ ምድቦች"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ይህ መተግበሪያ የማሳወቂያ ምድቦች የሉትም"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-am/strings_tv.xml b/packages/SystemUI/res/values-am/strings_tv.xml
index cd32b93..89fd692 100644
--- a/packages/SystemUI/res/values-am/strings_tv.xml
+++ b/packages/SystemUI/res/values-am/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"ፎቶ በፎቶ"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(ርዕስ የሌለው ፕሮግራም)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIPን ዝጋ"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"ሙሉ ማያ ገጽ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index c083fd1..17480fe 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -556,7 +556,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"إيقاف"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"باستخدام عناصر التحكم في إشعار التشغيل، يمكنك تعيين مستوى الأهمية من 0 إلى 5 لإشعارات التطبيق. \n\n"<b>"المستوى 5"</b>" \n- العرض أعلى قائمة الإشعارات \n- يسمح بمقاطعة ملء الشاشة \n- الظهور الخاطف دائمًا \n\n"<b>"المستوى 4"</b>" \n- منع مقاطعة ملء الشاشة \n- الظهور الخاطف دائمًا \n\n"<b>"المستوى 3"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n\n"<b>"المستوى 2"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n- عدم إصدار أصوات واهتزاز \n\n"<b>"المستوى 1"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n- عدم إصدار أصوات أو اهتزاز أبدًا \n- الإخفاء من شاشة التأمين وشريط الحالة \n- العرض أسفل قائمة الإشعارات \n\n"<b>"المستوى 0"</b>" \n- حظر جميع الإشعارات من التطبيق"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"الإشعارات"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"لن تتلقى هذه الإشعارات بعد الآن."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"لن تتلقى هذه الإشعارات بعد الآن."</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> فئة إشعار"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"لا يحتوي هذا التطبيق على فئات إشعار"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-ar/strings_tv.xml b/packages/SystemUI/res/values-ar/strings_tv.xml
index dcc673d..fe4d943 100644
--- a/packages/SystemUI/res/values-ar/strings_tv.xml
+++ b/packages/SystemUI/res/values-ar/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"صورة داخل صورة"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(ليس هناك عنوان للبرنامج)"</string>
     <string name="pip_close" msgid="3480680679023423574">"‏إغلاق PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"ملء الشاشة"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index b0f813f..08c1ce5 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Deaktiv"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Enerji bildiriş nəzarəti ilə, tətbiq bildirişləri üçün əhəmiyyət səviyyəsini 0-dan 5-ə kimi ayarlaya bilərsiniz. \n\n"<b>"Səviyyə 5"</b>" \n- Bildiriş siyahısının yuxarı hissəsində göstərin \n- Tam ekran kəsintisinə icazə verin \n- Hər zaman izləyin \n\n"<b>"Səviyyə 4"</b>" \n- Tam ekran kəsintisinin qarşısını alın \n- Hər zaman izləyin \n\n"<b>"Level 3"</b>" \n- Tam ekran kəsintisinin qarşısını alın \n- Heç vaxt izləməyin \n\n"<b>"Level 2"</b>" \n- Tam ekran kəsintisinin qarşısını alın \n- Heç vaxt izləməyin \n- Heç vaxt səsliyə və ya vibrasiyaya qoymayın \n\n"<b>"Səviyyə 1"</b>" \n- Prevent full screen interruption \n- Heç vaxt izləməyin \n- Heç vaxt səsliyə və ya vibrasiyaya qoymayın \n- Ekran kilidi və ya status panelindən gizlədin \n- Bildiriş siyahısının yuxarı hissəsində göstərin \n\n"<b>"Səviyyə 0"</b>" \n- Bütün bildirişləri tətbiqdən blok edin"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Bildirişlər"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Bu bildirişlər daha sizə göndərilməyəcək."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Bu bildirişlər daha sizə göndərilməyəcək"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> bildiriş kateqoriyaları"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Bu tətbiqin bildiriş kateqoriyası yoxdur"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-az/strings_tv.xml b/packages/SystemUI/res/values-az/strings_tv.xml
index 5e2f8bb..532c8d6 100644
--- a/packages/SystemUI/res/values-az/strings_tv.xml
+++ b/packages/SystemUI/res/values-az/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Şəkil-içində-Şəkil"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Başlıqsız proqram)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP bağlayın"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Tam ekran"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 7c2cc18..a7e6f6a 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -473,7 +473,7 @@
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Brže dobijajte obaveštenja"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Pregledajte ih pre otključavanja"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Ne, hvala"</string>
-    <string name="hidden_notifications_setup" msgid="41079514801976810">"Podesi"</string>
+    <string name="hidden_notifications_setup" msgid="41079514801976810">"Aktiviraj"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="volume_zen_end_now" msgid="3179845345429841822">"Prekini odmah"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Proširi"</string>
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Isključeno"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Pomoću naprednih kontrola za obaveštenja možete da podesite nivo važnosti od 0. do 5. za obaveštenja aplikacije. \n\n"<b>"5. nivo"</b>" \n– Prikazuju se u vrhu liste obaveštenja \n- Dozvoli prekid režima celog ekrana \n– Uvek zaviruj \n\n"<b>"4. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Uvek zaviruj \n\n"<b>"3. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n\n"<b>"2. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n– Nikada ne proizvodi zvuk ili vibraciju \n\n"<b>"1. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n– Nikada ne proizvodi zvuk ili vibraciju \n– Sakrij na zaključanom ekranu i statusnoj traci \n– Prikazuju se u dnu liste obaveštenja \n\n"<b>"0. nivo"</b>" \n– Blokiraj sva obaveštenja iz aplikacije"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Obaveštenja"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Više nećete da dobijate ova obaveštenja."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Više nećete dobijati ova obaveštenja"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Kategorija obaveštenja: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ova aplikacija nema kategorije obaveštenja"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
@@ -739,7 +739,7 @@
     <string name="lockscreen_unlock_left" msgid="2043092136246951985">"I leva prečica otključava"</string>
     <string name="lockscreen_unlock_right" msgid="1529992940510318775">"I desna prečica otključava"</string>
     <string name="lockscreen_none" msgid="4783896034844841821">"Ništa"</string>
-    <string name="tuner_launch_app" msgid="1527264114781925348">"Pokretanje <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="tuner_launch_app" msgid="1527264114781925348">"Pokreni <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="tuner_other_apps" msgid="4726596850501162493">"Druge aplikacije"</string>
     <string name="tuner_circle" msgid="2340998864056901350">"Krug"</string>
     <string name="tuner_plus" msgid="6792960658533229675">"Plus"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
index b41782b..6be4046 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Slika u slici"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program bez naslova)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Zatvori PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Ceo ekran"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 8c4a617..ce90937 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -554,7 +554,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Выключана"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"З дапамогай пашыранага кіравання апавяшчэннямі вы можаце задаваць узровень важнасці апавяшчэнняў праграмы ад 0 да 5. \n\n"<b>"Узровень 5"</b>" \n- Паказваць уверсе спіса апавяшчэнняў \n- Дазваляць перапыняць рэжым поўнага экрана \n- Заўсёды дазваляць кароткі паказ \n\n"<b>"Узровень 4"</b>" \n- Забараняць перапыняць рэжым поўнага экрана \n- Заўсёды дазваляць кароткі паказ \n\n"<b>"Узровень 3"</b>" \n- Забараняць перапыняць рэжым поўнага экрана \n- Ніколі не дазваляць кароткі паказ \n\n"<b>"Узровень 2"</b>" \n- Забараняць перапыняць рэжым поўнага экрана \n- Ніколі не дазваляць кароткі паказ \n- Ніколі не прайграваць гук і не вібрыраваць \n\n"<b>"Узровень 1"</b>" \n- Забараняць перапыняць рэжым поўнага экрана \n- Ніколі не дазваляць кароткі паказ \n- Ніколі не прайграваць гук і не вібрыраваць \n- Хаваць з экрана блакіроўкі і панэлі стану \n- Паказваць унізе спіса апавяшчэнняў \n\n"<b>"Узровень 0"</b>" \n- Блакіраваць усе апавяшчэнні ад праграмы"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Апавяшчэнні"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Вы больш не будзеце атрымліваць гэтыя апавяшчэнні."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Вы больш не будзеце атрымліваць гэтыя апавяшчэнні"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Катэгорый апавяшчэнняў: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"У гэтай праграме няма катэгорый апавяшчэнняў"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-be/strings_tv.xml b/packages/SystemUI/res/values-be/strings_tv.xml
index a339d32..b9761b7 100644
--- a/packages/SystemUI/res/values-be/strings_tv.xml
+++ b/packages/SystemUI/res/values-be/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Відарыс у відарысе"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Праграма без назвы)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Закрыць PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Ва ўвесь экран"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index d818f28..b1f1ae9 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Изкл."</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"С помощта на контролите за известията можете да зададете ниво на важност от 0 до 5 за известията от дадено приложение. \n\n"<b>"Ниво 5"</b>" \n– Показване най-горе в списъка с известия. \n– Разрешаване на прекъсването на цял екран. \n– Известията винаги се показват мимолетно. \n\n"<b>"Ниво 4"</b>" \n– Предотвратяване на прекъсването на цял екран. \n– Известията винаги се показват мимолетно. \n\n"<b>"Ниво 3"</b>" \n– Предотвратяване на прекъсването на цял екран. \n– Известията никога не се показват мимолетно. \n\n"<b>"Ниво 2"</b>" \n– Предотвратяване на прекъсването на цял екран. \n– Известията никога не се показват мимолетно. \n– Без издаване на звуков сигнал и вибриране. \n\n"<b>"Ниво 1"</b>" \n– Предотвратяване на прекъсването на цял екран. \n– Известията никога не се показват мимолетно. \n– Без издаване на звуков сигнал и вибриране. \n– Скриване от заключения екран и лентата на състоянието. \n– Показване най-долу в списъка с известия. \n\n"<b>"Ниво 0"</b>" \n– Блокиране на всички известия от приложението."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Известия"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Вече няма да получавате тези известия."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Вече няма да получавате тези известия"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> категории известия"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"За това приложение няма категории на известията"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-bg/strings_tv.xml b/packages/SystemUI/res/values-bg/strings_tv.xml
index 40521bc..ffe9007 100644
--- a/packages/SystemUI/res/values-bg/strings_tv.xml
+++ b/packages/SystemUI/res/values-bg/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Картина в картина"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Програма без заглавие)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Затваряне на PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Цял екран"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 8180453..7392d04 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"বন্ধ আছে"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"পাওয়ার বিজ্ঞপ্তির নিয়ন্ত্রণগুলি ব্যহবার করে, আপনি কোনো অ্যাপ্লিকেশানের বিজ্ঞপ্তির জন্য ০ থেকে ৫ পর্যন্ত একটি গুরুত্বের লেভেলকে সেট করতে পারবেন৷ \n\n"<b>"লেভেল ৫"</b>" \n- বিজ্ঞপ্তি তালিকার শীর্ষে দেখায় \n- পূর্ণ স্ক্রীনের বাধাকে অনুমতি দেয় \n- সর্বদা স্ক্রীনে উপস্থিত হয় \n\n"<b>"লেভেল ৪"</b>" \n- পূর্ণ স্ক্রীনের বাধাকে আটকায় \n- সর্বদা স্ক্রীনে উপস্থিত হয় \n\n"<b>"লেভেল ৩"</b>" \n- পূর্ণ স্ক্রীনের বাধাকে আটকায় \n- কখনই স্ক্রীনে উপস্থিত হয় না \n\n"<b>"লেভেল ২"</b>" \n- পূর্ণ স্ক্রীনের বাধাকে আটকায় \n- কখনই স্ক্রীনে উপস্থিত হয় না \n- কখনই শব্দ এবং কম্পন করে না \n\n"<b>"লেভেল ১"</b>" \n- পূর্ণ স্ক্রীনের বাধাকে আটকায় \n- কখনই স্ক্রীনে উপস্থিত হয় না \n- কখনই শব্দ এবং কম্পন করে না \n- লক স্ক্রীন এবং স্থিতি দন্ড থেকে লুকায় \n- বিজ্ঞপ্তি তালিকার নীচের দিকে দেখায় \n\n"<b>"লেভেল ০"</b>" \n- অ্যাপ্লিকেশান থেকে সমস্ত বিজ্ঞপ্তিকে অবরূদ্ধ করে"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"বিজ্ঞপ্তি"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"আপনি আর এই বিজ্ঞপ্তিগুলি পাবেন না।"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"আপনি এই বিজ্ঞপ্তিগুলি আর পাবেন না"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> বিজ্ঞপ্তির বিভাগগুলি"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"এই অ্যাপটিতে বিজ্ঞপ্তির বিভাগ নেই"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-bn/strings_tv.xml b/packages/SystemUI/res/values-bn/strings_tv.xml
index 9c6d5bc..ed95ac4 100644
--- a/packages/SystemUI/res/values-bn/strings_tv.xml
+++ b/packages/SystemUI/res/values-bn/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"ছবির-মধ্যে-ছবি"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(শিরোনামহীন প্রোগ্রাম)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP বন্ধ করুন"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"পূর্ণ স্ক্রীন"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 4905db1..563d81b 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -552,7 +552,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Isključeno"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Uz kontrolu obavještenja o napajanju, možete postaviti nivo značaja obavještenja iz aplikacije, i to od nivoa 0 do 5. \n\n"<b>"Nivo 5"</b>" \n- Prikaži na vrhu liste obavještenja \n- Dopusti prekid prikaza cijelog ekrana \n- Uvijek izviruj \n\n"<b>"Nvio 4"</b>" \n- Spriječi prekid prikaza cijelog ekrana \n- Uvijek izviruj \n\n"<b>"Nivo 3"</b>" \n- Spriječi prekid prikaza cijelog ekrana \n- Nikad ne izviruj \n\n"<b>"Nivo 2"</b>" \n- Spriječi prekid prikaza cijelog ekrana \n- Nikad ne izviruj \n- Nikada ne puštaj zvuk ili vibraciju \n\n"<b>"Nivo 1"</b>" \n- Spriječi prekid prikaza cijelog ekrana \n- Nikada ne izviruj \n- Nikada ne puštaj zvuk ili vibraciju \n- Sakrij sa ekrana za zaključavanje i statusne trake \n- Prikaži na dnu liste obavještenja \n\n"<b>"Nivo 0"</b>" \n- Blokiraj sva obavještenja iz aplikacije"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Obavještenja"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Nećete više primati ova obavještenja."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Nećete više primati ova obavještenja"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Kategorije obavještenja: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ova aplikacija nema kategorije obavještenja"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-bs/strings_tv.xml b/packages/SystemUI/res/values-bs/strings_tv.xml
index 932b9ce..b0b3612 100644
--- a/packages/SystemUI/res/values-bs/strings_tv.xml
+++ b/packages/SystemUI/res/values-bs/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Slika u slici"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program bez naslova)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Zatvori PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Cijeli ekran"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index e5696f9..5858bb8 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -206,12 +206,12 @@
     <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"S\'ha desactivat el mode No molestis."</string>
     <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"S\'ha activat el mode No molestis."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth."</string>
-    <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"El Bluetooth està desactivat."</string>
-    <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"El Bluetooth està activat."</string>
+    <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth desactivat."</string>
+    <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth activat."</string>
     <string name="accessibility_quick_settings_bluetooth_connecting" msgid="6953242966685343855">"S\'està connectant el Bluetooth."</string>
-    <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"El Bluetooth està connectat."</string>
-    <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"El Bluetooth està desactivat."</string>
-    <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"El Bluetooth està activat."</string>
+    <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"Bluetooth connectat."</string>
+    <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"Bluetooth desactivat."</string>
+    <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"Bluetooth activat."</string>
     <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"Informes d\'ubicació desactivats"</string>
     <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"Informes d\'ubicació activats"</string>
     <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"Els informes d\'ubicació estan desactivats."</string>
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desactivat"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Amb els controls de notificació millorats, pots establir un nivell d\'importància d\'entre 0 i 5 per a les notificacions d\'una aplicació. \n\n"<b>"Nivell 5"</b>" \n- Mostra les notificacions a la part superior de la llista \n- Permet la interrupció de la pantalla completa \n- Permet sempre la previsualització \n\n"<b>"Nivell 4"</b>" \n- No permet la interrupció de la pantalla completa \n- Permet sempre la previsualització \n\n"<b>"Nivell 3"</b>" \n- No permet la interrupció de la pantalla completa \n- No permet mai la previsualització \n\n"<b>"Nivell 2"</b>" \n- No permet la interrupció de la pantalla completa \n- No permet mai la previsualització \n- Les notificacions no poden emetre sons ni vibracions \n\n"<b>"Nivell 1"</b>" \n- No permet la interrupció de la pantalla completa \n- No permet mai la previsualització \n- No activa mai el so ni la vibració \n- Amaga les notificacions de la pantalla de bloqueig i de la barra d\'estat \n- Mostra les notificacions a la part inferior de la llista \n\n"<b>"Nivell 0"</b>" \n- Bloqueja totes les notificacions de l\'aplicació"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificacions"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ja no rebràs aquestes notificacions."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ja no rebràs aquestes notificacions"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categories de notificació"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Aquesta aplicació no té categories de notificació"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-ca/strings_tv.xml b/packages/SystemUI/res/values-ca/strings_tv.xml
index 9bfbb69..6e9fae5 100644
--- a/packages/SystemUI/res/values-ca/strings_tv.xml
+++ b/packages/SystemUI/res/values-ca/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Imatge en imatge"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Programa sense títol)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Tanca PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Pantalla completa"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 83138b4..1101217 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -554,7 +554,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Vypnuto"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Rozšířené ovládací prvky oznámení umožňují nastavit úroveň důležitosti oznámení aplikace od 0 do 5. \n\n"<b>"Úroveň 5"</b>" \n– Zobrazit na začátku seznamu oznámení \n– Povolit vyrušení na celou obrazovku \n– Vždy zobrazit náhled \n\n"<b>"Úroveň 4"</b>" \n– Zabránit vyrušení na celou obrazovku \n– Vždy zobrazit náhled \n\n"<b>"Úroveň 3"</b>" \n– Zabránit vyrušení na celou obrazovku \n– Nikdy nezobrazovat náhled \n\n"<b>"Úroveň 2"</b>" \n– Zabránit vyrušení na celou obrazovku \n– Nikdy nezobrazovat náhled \n– Nikdy nevydávat žádný zvukový signál ani nevibrovat \n\n"<b>"Úroveň 1"</b>" \n– Zabránit vyrušení na celou obrazovku \n– Nikdy nezobrazovat náhled \n– Nikdy nevydávat zvukový signál ani nevibrovat \n– Skrýt z obrazovky uzamčení a stavového řádku \n– Zobrazovat na konci seznamu oznámení \n\n"<b>";Úroveň 0"</b>" \n– Blokovat všechna oznámení z aplikace"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Oznámení"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Tato oznámení již nebudete dostávat."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Tato oznámení již nebudete dostávat"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Kategorie oznámení: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Tato aplikace nemá kategorie oznámení"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-cs/strings_tv.xml b/packages/SystemUI/res/values-cs/strings_tv.xml
index 77806de..f27974f 100644
--- a/packages/SystemUI/res/values-cs/strings_tv.xml
+++ b/packages/SystemUI/res/values-cs/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Obraz v obraze"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Bez názvu)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Ukončit PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Celá obrazovka"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 5a859de..3a0a083 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Fra"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Med kontrolelementer til underretninger om strøm kan du konfigurere et vigtighedsniveau fra 0 til 5 for en apps underretninger. \n\n"<b>"Niveau 5"</b>\n"- Vis øverst på listen over underretninger \n- Tillad afbrydelse af fuld skærm \n- Se altid smugkig \n\n"<b>"Niveau 4"</b>\n"- Ingen afbrydelse af fuld skærm \n- Se altid smugkig \n\n"<b>"Niveau 3"</b>\n"- Ingen afbrydelse af fuld skærm \n- Se aldrig smugkig \n\n"<b>"Niveau 2"</b>\n"- Ingen afbrydelse af fuld skærm \n Se aldrig smugkig \n- Ingen lyd og vibration \n\n"<b>"Niveau 1"</b>\n"- Ingen afbrydelse af fuld skærm \n- Se aldrig smugkig \n- Ingen lyd eller vibration \n- Skjul fra låseskærm og statusbjælke \n- Vis nederst på listen over underretninger \n\n"<b>"Niveau 0"</b>\n"- Bloker alle underretninger fra appen."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Underretninger"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Du modtager ikke længere disse underretninger."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Du modtager ikke længere disse underretninger"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> underretningskategorier"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Denne app har ingen underretningskategorier"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-da/strings_tv.xml b/packages/SystemUI/res/values-da/strings_tv.xml
index 4fe671b..d24cb3a 100644
--- a/packages/SystemUI/res/values-da/strings_tv.xml
+++ b/packages/SystemUI/res/values-da/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Integreret billede"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program uden titel)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Luk PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Fuld skærm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index d9af495..55480fb 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Aus"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Mit den erweiterten Benachrichtigungseinstellungen kannst du für App-Benachrichtigungen eine Wichtigkeitsstufe von 0 bis 5 festlegen. \n\n"<b>"Stufe 5"</b>" \n- Auf der Benachrichtigungsleiste ganz oben anzeigen \n- Vollbildunterbrechung zulassen \n- Immer kurz einblenden \n\n"<b>"Stufe 4"</b>" \n- Keine Vollbildunterbrechung \n- Immer kurz einblenden \n\n"<b>"Stufe 3"</b>" \n- Keine Vollbildunterbrechung \n- Nie kurz einblenden \n\n"<b>"Stufe 2"</b>" \n- Keine Vollbildunterbrechung \n- Nie kurz einblenden \n- Weder Ton noch Vibration \n\n"<b>"Stufe 1"</b>" \n- Keine Vollbildunterbrechung \n- Nie kurz einblenden \n- Weder Ton noch Vibration \n- Auf Sperrbildschirm und Statusleiste verbergen \n- Auf der Benachrichtigungsleiste ganz unten anzeigen \n\n"<b>"Stufe 0"</b>" \n- Alle Benachrichtigungen der App sperren"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Benachrichtigungen"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Du erhältst diese Benachrichtigungen nicht mehr."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Du erhältst diese Benachrichtigungen nicht mehr"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> Benachrichtigungskategorien"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Diese App hat keine Benachrichtigungskategorien"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-de/strings_tv.xml b/packages/SystemUI/res/values-de/strings_tv.xml
index 733ed12..c83a52e 100644
--- a/packages/SystemUI/res/values-de/strings_tv.xml
+++ b/packages/SystemUI/res/values-de/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Bild-in-Bild"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Kein Programmtitel)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP schließen"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Vollbild"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 80f6065..53d29fe 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Ανενεργή"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Με τα στοιχεία ελέγχου ειδοποίησης ισχύος, μπορείτε να ορίσετε ένα επίπεδο βαρύτητας από 0 έως 5 για τις ειδοποιήσεις μιας εφαρμογής. \n\n"<b>"Επίπεδο 5"</b>" \n- Εμφάνιση στην κορυφή της λίστας ειδοποιήσεων \n- Να επιτρέπεται η διακοπή πλήρους οθόνης \n- Να γίνεται πάντα σύντομη προβολή \n\n"<b>"Επίπεδο 4"</b>" \n- Αποτροπή διακοπής πλήρους οθόνης \n- Να γίνεται πάντα σύντομη προβολή \n\n"<b>"Επίπεδο 3"</b>" \n- Αποτροπή διακοπής πλήρους οθόνης \n- Να μην γίνεται ποτέ σύντομη προβολή \n\n"<b>"Επίπεδο 2"</b>" \n- Αποτροπή διακοπής πλήρους οθόνης \n- Να μην γίνεται ποτέ σύντομη προβολή \n- Να μην χρησιμοποιείται ποτέ ήχος και δόνηση \n\n"<b>"Επίπεδο 1"</b>" \n- Αποτροπή διακοπής πλήρους οθόνης \n- Να μην γίνεται ποτέ σύντομη προβολή \n- Να μην χρησιμοποιείται ποτέ ήχος και δόνηση \n- Απόκρυψη από την οθόνη κλειδώματος και τη γραμμή κατάστασης \n- Εμφάνιση στο κάτω μέρος της λίστας ειδοποιήσεων \n\n"<b>"Επίπεδο 0"</b>" \n- Αποκλεισμός όλων των ειδοποιήσεων από την εφαρμογή"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Ειδοποιήσεις"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Δεν θα λαμβάνεται πλέον αυτές τις ειδοποιήσεις."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Δεν θα λαμβάνετε πλέον αυτές τις ειδοποιήσεις"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> κατηγορίες ειδοποιήσεων"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Αυτή η εφαρμογή δεν διαθέτει κατηγορίες ειδοποιήσεων"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-el/strings_tv.xml b/packages/SystemUI/res/values-el/strings_tv.xml
index 7d92748..4e613ce 100644
--- a/packages/SystemUI/res/values-el/strings_tv.xml
+++ b/packages/SystemUI/res/values-el/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Λειτουργία Picture-in-picture"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Δεν υπάρχει τίτλος προγράμματος)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Κλείσιμο PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Πλήρης οθόνη"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 056a1e0..874bc67 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Off"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"With power notification controls, you can set an importance level from 0 to 5 for an app\'s notifications. \n\n"<b>"Level 5"</b>" \n- Show at the top of the notification list \n- Allow full screen interruption \n- Always peek \n\n"<b>"Level 4"</b>" \n- Prevent full screen interruption \n- Always peek \n\n"<b>"Level 3"</b>" \n- Prevent full screen interruption \n- Never peek \n\n"<b>"Level 2"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound and vibration \n\n"<b>"Level 1"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound or vibrate \n- Hide from lock screen and status bar \n- Show at the bottom of the notification list \n\n"<b>"Level 0"</b>" \n- Block all notifications from the app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"You won\'t get these notifications anymore."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"You won\'t get these notifications anymore"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> notification categories"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"This app doesn\'t have notification categories"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-en-rAU/strings_tv.xml b/packages/SystemUI/res/values-en-rAU/strings_tv.xml
index 16fdfe1..ffcd655 100644
--- a/packages/SystemUI/res/values-en-rAU/strings_tv.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Picture-in-Picture"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(No title program)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Close PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 056a1e0..874bc67 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Off"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"With power notification controls, you can set an importance level from 0 to 5 for an app\'s notifications. \n\n"<b>"Level 5"</b>" \n- Show at the top of the notification list \n- Allow full screen interruption \n- Always peek \n\n"<b>"Level 4"</b>" \n- Prevent full screen interruption \n- Always peek \n\n"<b>"Level 3"</b>" \n- Prevent full screen interruption \n- Never peek \n\n"<b>"Level 2"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound and vibration \n\n"<b>"Level 1"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound or vibrate \n- Hide from lock screen and status bar \n- Show at the bottom of the notification list \n\n"<b>"Level 0"</b>" \n- Block all notifications from the app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"You won\'t get these notifications anymore."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"You won\'t get these notifications anymore"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> notification categories"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"This app doesn\'t have notification categories"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-en-rGB/strings_tv.xml b/packages/SystemUI/res/values-en-rGB/strings_tv.xml
index 16fdfe1..ffcd655 100644
--- a/packages/SystemUI/res/values-en-rGB/strings_tv.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Picture-in-Picture"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(No title program)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Close PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 056a1e0..874bc67 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Off"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"With power notification controls, you can set an importance level from 0 to 5 for an app\'s notifications. \n\n"<b>"Level 5"</b>" \n- Show at the top of the notification list \n- Allow full screen interruption \n- Always peek \n\n"<b>"Level 4"</b>" \n- Prevent full screen interruption \n- Always peek \n\n"<b>"Level 3"</b>" \n- Prevent full screen interruption \n- Never peek \n\n"<b>"Level 2"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound and vibration \n\n"<b>"Level 1"</b>" \n- Prevent full screen interruption \n- Never peek \n- Never make sound or vibrate \n- Hide from lock screen and status bar \n- Show at the bottom of the notification list \n\n"<b>"Level 0"</b>" \n- Block all notifications from the app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"You won\'t get these notifications anymore."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"You won\'t get these notifications anymore"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> notification categories"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"This app doesn\'t have notification categories"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-en-rIN/strings_tv.xml b/packages/SystemUI/res/values-en-rIN/strings_tv.xml
index 16fdfe1..ffcd655 100644
--- a/packages/SystemUI/res/values-en-rIN/strings_tv.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Picture-in-Picture"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(No title program)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Close PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 3a69668..b690df1 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desactivado"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Con los controles de activación de notificaciones, puedes establecer un nivel de importancia para las notificaciones de una app. \n\n"<b>"Nivel 5"</b>" \n- Mostrar en la parte superior de la lista de notificaciones. \n- Permitir interrupción en la pantalla completa. \n- Mostrar siempre. \n\n"<b>"Nivel 4"</b>" \n- No permitir interrupción en la pantalla completa. \n- Mostrar siempre. \n\n"<b>"Nivel 3"</b>" \n- No permitir interrupción en la pantalla completa. \n- No mostrar. \n\n"<b>"Nivel 2"</b>" \n- No permitir interrupción en la pantalla completa. \n- No mostrar. \n- No sonar ni vibrar. \n\n"<b>"Nivel 1"</b>" \n- No permitir interrupción en la pantalla completa. \n- No mostrar. \n- No sonar ni vibrar. \n- Ocultar de la pantalla bloqueada y la barra de estado. \n- Mostrar al final de la lista de notificaciones. \n\n"<b>"Nivel 0"</b>" \n- Bloquear todas las notificaciones de la app."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificaciones"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ya no recibirás estas notificaciones."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ya no recibirás estas notificaciones"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorías de notificaciones"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Esta app no tiene categorías de notificación"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-es-rUS/strings_tv.xml b/packages/SystemUI/res/values-es-rUS/strings_tv.xml
index 04552a7..aabf59d 100644
--- a/packages/SystemUI/res/values-es-rUS/strings_tv.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Imagen en imagen"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Sin título de programa)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Cerrar PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Pantalla completa"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 999d625..2a98dcc 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desactivado"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Los controles de energía de las notificaciones permiten establecer un nivel de importancia de 0 a 5 para las notificaciones de las aplicaciones. \n\n"<b>"Nivel 5"</b>" \n- Mostrar en la parte superior de la lista de notificaciones \n- Permitir interrumpir en el modo de pantalla completa \n- Mostrar siempre \n\n"<b>"Nivel 4"</b>" \n- Evitar interrumpir en el modo de pantalla completa \n- Mostrar siempre \n\n"<b>"Nivel 3"</b>" \n- Evitar interrumpir en el modo de pantalla completa \n- No mostrar nunca \n\n"<b>"Nivel 2"</b>" \n- Evitar interrumpir en el modo de pantalla completa\n- No mostrar nunca \n- No emitir sonido ni vibrar nunca \n\n"<b>"Nivel 1"</b>" \n- Evitar interrumpir en el modo de pantalla completa \n- No mostrar nunca \n- No emitir sonido ni vibrar nunca \n- Ocultar de la pantalla de bloqueo y de la barra de estado \n- Mostrar en la parte inferior de la lista de notificaciones \n\n"<b>"Nivel 0"</b>" \n- Bloquear todas las notificaciones de la aplicación"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificaciones"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ya no recibirás estas notificaciones."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ya no recibirás estas notificaciones"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorías de notificación"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Esta aplicación no tiene categorías de notificación"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-es/strings_tv.xml b/packages/SystemUI/res/values-es/strings_tv.xml
index 04552a7..add06a7 100644
--- a/packages/SystemUI/res/values-es/strings_tv.xml
+++ b/packages/SystemUI/res/values-es/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Imagen en imagen"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Programa sin título)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Cerrar PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Pantalla completa"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 05085fa..72c382a 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Väljas"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Toite märguannete juhtnuppudega saate määrata rakenduse märguannete tähtsuse taseme vahemikus 0–5. \n\n"<b>"5. tase"</b>" \n- Kuva märguannete loendi ülaosas\n- Luba täisekraanil häirimine \n- Kuva alati ekraani servas \n\n"<b>"4. tase"</b>" \n- Keela täisekraanil häirimine \n- Kuva alati ekraani servas \n\n"<b>"3. tase"</b>" \n- Keela täisekraanil häirimine \n- Ära kunagi kuva ekraani servas \n\n"<b>"2. tase"</b>" \n- Keela täisekraanil häirimine \n- Ära kunagi kuva ekraani servas \n- Ära kunagi helise ega vibreeri \n\n"<b>"1. tase"</b>" \n- Keela täisekraanil häirimine \n- Ära kunagi kuva ekraani servas \n- Ära kunagi helise ega vibreeri \n- Peida lukustuskuval ja olekuribal \n- Kuva märguannete loendi allosas \n\n"<b>"Tase 0"</b>" \n- Blokeeri kõik rakenduse märguanded"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Märguanded"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Te ei saa enam neid märguandeid."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Te ei saa enam neid märguandeid"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> märguandekategooriat"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Sellel rakendusel ei ole märguannete kategooriaid"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-et/strings_tv.xml b/packages/SystemUI/res/values-et/strings_tv.xml
index c05ccd6..bfd3884 100644
--- a/packages/SystemUI/res/values-et/strings_tv.xml
+++ b/packages/SystemUI/res/values-et/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Pilt pildis"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Programmi pealkiri puudub)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Sule PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Täisekraan"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 6aadacb..42386e2 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desaktibatuta"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Bateria-mailaren arabera jakinarazpenak kontrolatzeko aukerekin, 0 eta 5 bitarteko garrantzi-mailetan sailka ditzakezu aplikazioen jakinarazpenak. \n\n"<b>"5. maila"</b>" \n- Erakutsi jakinarazpenen zerrendaren goialdean. \n- Baimendu etetea pantaila osoko moduan zaudenean. \n- Agerrarazi beti jakinarazpenak. \n\n"<b>"4. maila"</b>" \n- Galarazi etetea pantaila osoko moduan zaudenean. \n- Agerrarazi beti jakinarazpenak. \n\n"<b>"3. maila"</b>" \n- Galarazi etetea pantaila osoko moduan zaudenean. \n- Ez agerrarazi jakinarazpenik inoiz. \n\n"<b>"2. maila"</b>" \n- Galarazi etetea pantaila osoko moduan zaudenean. \n- Ez agerrarazi jakinarazpenik inoiz. \n- Ez egin soinurik edo dardararik inoiz. \n\n"<b>"1. maila"</b>" \n- Galarazi etetea pantaila osoko moduan zaudenean. \n- Ez agerrarazi jakinarazpenik inoiz. \n- Ez egin soinurik edo dardararik inoiz. \n- Ezkutatu pantaila blokeatutik eta egoera-barratik. \n- Erakutsi jakinarazpenen zerrendaren behealdean. \n\n"<b>"0. maila"</b>" \n- Blokeatu aplikazioaren jakinarazpen guztiak."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Jakinarazpenak"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Aurrerantzean ez duzu jasoko horrelako jakinarazpenik."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Aurrerantzean ez duzu jasoko horrelako jakinarazpenik"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Jakinarazpenen <xliff:g id="NUMBER">%d</xliff:g> kategoria"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Aplikazio honek ez du jakinarazpen-kategoriarik"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-eu/strings_tv.xml b/packages/SystemUI/res/values-eu/strings_tv.xml
index e145f09..6dd81a6 100644
--- a/packages/SystemUI/res/values-eu/strings_tv.xml
+++ b/packages/SystemUI/res/values-eu/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Pantaila txikia"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Programa izengabea)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Itxi PIPa"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Pantaila osoa"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 63050ae..7197617 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"خاموش"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"با کنترل‌های قدرتمند اعلان می‌توانید سطح اهمیت اعلان‌های هر برنامه را از ۰ تا ۵ تعیین کنید. \n\n"<b>"سطح ۵"</b>" \n- در صدر فهرست اعلان‌ها نشان داده می‌شود \n- وقفه برای نمایش تمام‌صفحه مجاز است \n- همیشه اجمالی نشان داده می‌شود \n\n"<b>"سطح ۴"</b>" \n- وقفه برای نمایش تمام‌صفحه مجاز نیست \n- همیشه اجمالی نشان داده می‌شود \n\n"<b>"سطح ۳"</b>" \n- وقفه برای نمایش تمام‌صفحه مجاز نیست \n- هیچ‌وقت اجمالی نشان داده نمی‌شود \n\n"<b>"سطح ۲"</b>" \n- وقفه برای نمایش تمام‌صفحه مجاز نیست \n- هیچ‌وقت اجمالی نشان داده نمی‌شود \n- هیچ‌وقت صدا و لرزش ایجاد نمی‌کند \n\n"<b>"سطح ۱"</b>" \n- نمایش تمام صفحه مجاز نیست \n- هیچ‌وقت اجمالی نشان داده نمی‌شود \n- هیچ‌وقت صدا یا لرزش ایجاد نمی‌کند \n- در قفل صفحه و نوار وضعیت پنهان است \n- در پایین فهرست اعلان‌ها نشان داده می‌شود \n\n"<b>"سطح ۰"</b>" \n- همه اعلان‌های این برنامه مسدود است"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"اعلان‌ها"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"دیگر این اعلان‌ها را دریافت نخواهید کرد."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"دیگر این اعلان‌ها را دریافت نخواهید کرد"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> دسته اعلان"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"این برنامه دسته اعلان ندارد"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-fa/strings_tv.xml b/packages/SystemUI/res/values-fa/strings_tv.xml
index 9507a6f..e34fccb2 100644
--- a/packages/SystemUI/res/values-fa/strings_tv.xml
+++ b/packages/SystemUI/res/values-fa/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"تصویر در تصویر"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(برنامه بدون عنوان)"</string>
     <string name="pip_close" msgid="3480680679023423574">"‏بستن PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"تمام صفحه"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index ec6a6d9..67bda58 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Pois käytöstä"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Ilmoitusten tehohallinnan avulla voit määrittää sovelluksen ilmoituksille tärkeystason väliltä 0–5. \n\n"<b>"Taso 5"</b>" \n– Ilmoitukset näytetään ilmoitusluettelon yläosassa \n– Näkyminen koko näytön tilassa sallitaan \n– Ilmoitukset kurkistavat aina näytölle\n\n"<b>"Taso 4"</b>" \n– Näkyminen koko näytön tilassa estetään \n– Ilmoitukset kurkistavat aina näytölle \n\n"<b>"Taso 3"</b>" \n– Näkyminen koko näytön tilassa estetään \n– Ei kurkistamista \n\n"<b>"Taso 2"</b>" \n– Näkyminen koko näytön tilassa estetään \n– Ei kurkistamista \n– Ei ääniä eikä värinää \n\n"<b>"Taso 1"</b>" \n– Näkyminen koko näytön tilassa estetään \n– Ei kurkistamista \n– Ei ääniä eikä värinää \n– Ilmoitukset piilotetaan lukitusnäytöltä ja tilapalkista \n– Ilmoitukset näytetään ilmoitusluettelon alaosassa \n\n"<b>"Taso 0"</b>" \n– Kaikki sovelluksen ilmoitukset estetään"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Ilmoitukset"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Et saa näitä ilmoituksia enää."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Et saa näitä ilmoituksia enää."</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ilmoitusluokkaa"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Tällä sovelluksella ei ole ilmoitusluokkia."</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-fi/strings_tv.xml b/packages/SystemUI/res/values-fi/strings_tv.xml
index 1d91f6f..0ee98b2 100644
--- a/packages/SystemUI/res/values-fi/strings_tv.xml
+++ b/packages/SystemUI/res/values-fi/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Kuva kuvassa"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Nimetön)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Sulje PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Koko näyttö"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 77a545e..caf219b 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Désactivé"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Avec les réglages avancés des notifications, vous pouvez définir un degré d\'importance de 0 à 5 pour les notifications d\'une application. \n\n"<b>"Niveau 5"</b>" \n- Afficher dans le haut de la liste des notifications \n- Autoriser les interruptions en mode plein écran \n- Toujours afficher les aperçus \n\n"<b>"Niveau 4"</b>" \n- Empêcher les interruptions en mode plein écran \n- Toujours afficher les aperçus \n\n"<b>"Niveau 3"</b>" \n- Empêcher les interruptions en mode plein écran \n- Ne jamais afficher les aperçus \n\n"<b>"Niveau 2"</b>" \n- Empêcher les interruptions en mode plein écran \n- Ne jamais afficher les aperçus \n- Ne pas autoriser les sons et les vibrations \n\n"<b>"Niveau 1"</b>" \n- Empêcher les interruptions en mode plein écran \n- Ne jamais afficher les aperçus \n- Ne pas autoriser les sons et les vibrations \n- Masquer de l\'écran de verrouillage et de la barre d\'état status bar \n- Afficher dans le bas de la liste des notifications \n\n"<b>"Level 0"</b>" \n- Bloquer toutes les notifications de l\'application"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Vous ne recevrez plus ces notifications."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Vous ne recevrez plus ces notifications"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> catégories de notification"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Cette application n\'a pas de catégories de notification"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
index ec27fd0..f8769b8 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Incrustation d\'image"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Aucun programme de titre)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Fermer mode IDI"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Plein écran"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 3b3ef48..8fff5ad 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Désactivé"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Grâce aux commandes de gestion des notifications, vous pouvez définir le niveau d\'importance (compris entre 0 et 5) des notifications d\'une application. \n\n"<b>"Niveau 5"</b>" \n- Afficher en haut de la liste des notifications \n- Autoriser l\'interruption en plein écran \n- Toujours en aperçu \n\n"<b>"Niveau 4"</b>" \n- Empêcher l\'interruption en plein écran \n- Toujours en aperçu \n\n"<b>"Niveau 3"</b>" \n- Empêcher l\'interruption en plein écran \n- Jamais en aperçu \n\n"<b>"Niveau 2"</b>" \n- Empêcher l\'interruption en plein écran \n- Jamais en aperçu \n- Ne jamais émettre de signal sonore ni déclencher le vibreur \n\n"<b>"Niveau 1"</b>" \n- Empêcher l\'interruption en plein écran \n- Jamais en aperçu \n- Ne jamais émettre de signal sonore ni déclencher le vibreur \n- Masquer les notifications dans l\'écran de verrouillage et la barre d\'état \n- Afficher au bas de la liste des notifications \n\n"<b>"Niveau 0"</b>" \n- Bloquer toutes les notifications de l\'application"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Vous ne recevrez plus ces notifications."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Vous ne recevrez plus ces notifications"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> catégories de notification"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Cette application n\'a pas de catégories de notification"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-fr/strings_tv.xml b/packages/SystemUI/res/values-fr/strings_tv.xml
index 0fd0dff..3c0ad7a 100644
--- a/packages/SystemUI/res/values-fr/strings_tv.xml
+++ b/packages/SystemUI/res/values-fr/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Picture-in-Picture"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Programme sans titre)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Fermer mode PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Plein écran"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 05d41f0..2abd5ec 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desactivar"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Cos controis de notificacións mellorados, podes asignarlles un nivel de importancia comprendido entre 0 e 5 ás notificacións dunha aplicación determinada. \n\n"<b>"Nivel 5"</b>" \n- Mostrar na parte superior da lista de notificacións. \n- Permitir interrupcións no modo de pantalla completa. \n- Mostrar sempre. \n\n"<b>"Nivel 4"</b>" \n- Impedir interrupcións no modo de pantalla completa. \n- Mostrar sempre. \n\n"<b>"Nivel 3"</b>" \n- Impedir interrupcións no modo de pantalla completa. \n- Non mostrar nunca. \n\n"<b>"Nivel 2"</b>" \n- Impedir interrupcións no modo de pantalla completa. \n- Non mostrar nunca. \n- Non soar nin vibrar nunca. \n\n"<b>"Nivel 1"</b>" \n- Impedir interrupcións no modo de pantalla completa. \n- Non mostrar nunca. \n- Non soar nin vibrar nunca. \n- Ocultar na pantalla de bloqueo e na barra de estado. \n- Mostrar na parte inferior da lista de notificacións. \n\n"<b>"Nivel 0"</b>" \n- Bloquear todas as notificacións da aplicación."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificacións"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Deixarás de recibir estas notificacións."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Deixarás de recibir estas notificacións"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorías de notificacións"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Esta aplicación non ten categorías de notificacións"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-gl/strings_tv.xml b/packages/SystemUI/res/values-gl/strings_tv.xml
index 9ca6759..c7f0ce1 100644
--- a/packages/SystemUI/res/values-gl/strings_tv.xml
+++ b/packages/SystemUI/res/values-gl/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Imaxe superposta"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Programa sen título)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Pechar PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Pantalla completa"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index d0131e2..ede86c4 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"બંધ"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"પાવર સૂચના નિયંત્રણો સાથે, તમે ઍપ્લિકેશનની સૂચનાઓ માટે 0 થી 5 સુધીના મહત્વના સ્તરને સેટ કરી શકો છો. \n\n"<b>"સ્તર 5"</b>" \n- સૂચના સૂચિની ટોચ પર બતાવો \n- પૂર્ણ સ્ક્રીન અવરોધની મંજૂરી આપો \n- હંમેશાં ત્વરિત દૃષ્ટિ કરો \n\n"<b>"સ્તર 4"</b>" \n- પૂર્ણ સ્ક્રીન અવરોધ અટકાવો \n- હંમેશાં ત્વરિત દૃષ્ટિ કરો \n\n"<b>"સ્તર 3"</b>" \n- પૂર્ણ સ્ક્રીન અવરોધ અટકાવો \n- ક્યારેય ત્વરિત દૃષ્ટિ કરશો નહીં \n\n"<b>"સ્તર 2"</b>" \n- પૂર્ણ સ્ક્રીન અવરોધ અટકાવો \n- ક્યારેય ત્વરિત દૃષ્ટિ કરશો નહીં \n- ક્યારેય અવાજ અને વાઇબ્રેશન કરશો નહીં \n\n"<b>"સ્તર 1"</b>" \n- પૂર્ણ સ્ક્રીન અવરોધ અટકાવો \n- ક્યારેય ત્વરિત દૃષ્ટિ કરશો નહીં \n- ક્યારેય અવાજ અથવા વાઇબ્રેટ કરશો નહીં \n- લૉક સ્ક્રીન અને સ્થિતિ બારથી છુપાવો \n- સૂચના સૂચિના તળિયા પર બતાવો \n\n"<b>"સ્તર 0"</b>" \n- ઍપ્લિકેશનની તમામ સૂચનાઓને અવરોધિત કરો"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"સૂચનાઓ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"તમને હવે આ સૂચનાઓ મળશે નહીં."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"તમને હવે આ સૂચનાઓ મળશે નહીં"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> સૂચના કૅટેગરીઓ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"આ ઍપ્લિકેશનમાં સૂચના કૅટેગરી નથી"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-gu/strings_tv.xml b/packages/SystemUI/res/values-gu/strings_tv.xml
index e53c524..5b98fb9 100644
--- a/packages/SystemUI/res/values-gu/strings_tv.xml
+++ b/packages/SystemUI/res/values-gu/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"ચિત્રમાં-ચિત્ર"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(કોઈ ટાઇટલ પ્રોગ્રામ નથી)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP બંધ કરો"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"પૂર્ણ સ્ક્રીન"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index f2baa04..3ccd7b2 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"बंद"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"पावर नोटिफ़िकेशन नियंत्रण के द्वारा, आप किसी ऐप्लिकेशन के नोटिफ़िकेशन के लिए 0 से 5 तक महत्व का लेवल सेट कर सकते हैं. \n\n"<b>"लेवल 5"</b>" \n- नोटिफ़िकेशन सूची के शीर्ष पर दिखाएं \n- पूर्ण स्क्रीन बाधा की अनुमति दें \n- हमेशा तांक-झांक करें \n\n"<b>"लेवल 4"</b>" \n- पूर्ण स्क्रीन बाधा को रोकें \n- हमेशा तांक-झांक करें \n\n"<b>"लेवल 3"</b>" \n- पूर्ण स्क्रीन बाधा को रोकें \n- कभी भी तांक-झांक ना करें \n\n"<b>"लेवल 2"</b>" \n- पूर्ण स्क्रीन बाधा को रोकें \n- कभी भी तांक-झांक ना करें \n- कभी भी ध्वनि या कंपन ना करें \n\n"<b>"लेवल 1"</b>" \n- पूर्ण स्क्रीन बाधा को रोकें \n- कभी भी तांक-झांक ना करें \n- कभी भी ध्वनि या कंपन ना करें \n- लॉक स्क्रीन और स्थिति बार से छिपाएं \n- नोटिफ़िकेशन सूची के नीचे दिखाएं \n\n"<b>"लेवल 0"</b>" \n- ऐप्लिकेशन के सभी नोटिफ़िकेशन अवरुद्ध कर दें"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"नोटिफ़िकेशन"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"अब आपको ये नोटिफ़िकेशन नहीं मिलेंगे."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"अब आपको ये नोटिफ़िकेशन नहीं मिलेंगे"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"नोटिफ़िकेशन की <xliff:g id="NUMBER">%d</xliff:g> श्रेणियां"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"इस ऐप्लिकेशन में नोटिफ़िकेशन श्रेणियां नहीं हैं"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-hi/strings_tv.xml b/packages/SystemUI/res/values-hi/strings_tv.xml
index 6c90d66..39f06f6 100644
--- a/packages/SystemUI/res/values-hi/strings_tv.xml
+++ b/packages/SystemUI/res/values-hi/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"चित्र में चित्र"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(कोई शीर्षक कार्यक्रम नहीं)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP बंद करें"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"पूर्ण स्‍क्रीन"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 2b6bceb..373a1ad 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Isključeno"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Napredne kontrole obavijesti omogućuju vam da postavite razinu važnosti za obavijesti aplikacije od 0 do 5. \n\n"<b>"Razina 5"</b>" \n– prikaži na vrhu popisa obavijesti \n– dopusti prekide prikaza na cijelom zaslonu \n– uvijek dopusti brzi pregled \n\n"<b>"Razina 4"</b>" \n– onemogući prekid prikaza na cijelom zaslonu \n– uvijek dopusti brzi pregled \n\n"<b>"Razina 3"</b>" \n– onemogući prekid prikaza na cijelom zaslonu \n– nikad ne dopusti brzi pregled\n\n"<b>"Razina 2"</b>" \n– onemogući prekid prikaza na cijelom zaslonu \n– nikad ne dopusti brzi pregled \n– nikad ne emitiraj zvuk ni vibraciju \n\n"<b>"Razina 1"</b>" \n– onemogući prekid prikaza na cijelom zaslonu \n– nikad ne dopusti brzi pregled \n– nikad ne emitiraj zvuk ni vibraciju \n– ne prikazuj na zaključanom zaslonu i traci statusa \n– prikaži na dnu popisa obavijesti \n\n"<b>"Razina 0"</b>" \n– blokiraj sve obavijesti aplikacije"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Obavijesti"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Više nećete primati te obavijesti."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Više nećete primati te obavijesti"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Broj kategorija obavijesti: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ova aplikacija nema kategorije obavijesti"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-hr/strings_tv.xml b/packages/SystemUI/res/values-hr/strings_tv.xml
index 37854bd..7cbaa26 100644
--- a/packages/SystemUI/res/values-hr/strings_tv.xml
+++ b/packages/SystemUI/res/values-hr/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Slika u slici"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program bez naslova)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Zatvori PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Cijeli zaslon"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index dd231b7..7710ad8 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Kikapcsolva"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Az értesítési beállítások révén 0-tól 5-ig állíthatja be a fontossági szintet az alkalmazás értesítéseinél. \n\n"<b>"5. szint"</b>" \n– Megjelenítés az értesítési lista tetején \n– Teljes képernyő megszakításának engedélyezése \n– Mindig felugrik \n\n"<b>"4. szint"</b>" \n– Teljes képernyő megszakításának megakadályozása \n– Mindig felugrik \n\n"<b>"3. szint"</b>" \n– Teljes képernyő megszakításának megakadályozása \n– Soha nem ugrik fel \n\n"<b>"2. szint"</b>" \n– Teljes képernyő megszakításának megakadályozása \n– Soha nem ugrik fel \n– Soha nincs hangjelzés és rezgés \n\n"<b>"1. szint"</b>" \n– Teljes képernyő megszakításának megakadályozása \n– Soha nem ugrik fel \n– Soha nincs hangjelzés vagy rezgés \n– Elrejtés a lezárási képernyőről és az állapotsávról \n– Megjelenítés az értesítési lista alján \n\n"<b>"0. szint"</b>" \n– Az alkalmazás összes értesítésének letiltása"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Értesítések"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Többé nem jelennek meg ezek az értesítések."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Többé nem jelennek meg ezek az értesítések"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> értesítéskategória"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Az alkalmazás nem rendelkezik értesítési kategóriákkal"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-hu/strings_tv.xml b/packages/SystemUI/res/values-hu/strings_tv.xml
index f2f4893..2fd5ded 100644
--- a/packages/SystemUI/res/values-hu/strings_tv.xml
+++ b/packages/SystemUI/res/values-hu/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Kép a képben"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Cím nélküli program)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP bezárása"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Teljes képernyő"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 0ef1fcf..d3cd0639 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Անջատել"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Ծանուցումների ընդլայնված կառավարման օգնությամբ կարող եք յուրաքանչյուր հավելվածի ծանուցումների համար նշանակել կարևորության աստիճան՝ 0-5 սահմաններում: \n\n"<b>"5-րդ աստիճան"</b>" \n- Ցուցադրել ծանուցումների ցանկի վերևում \n- Թույլատրել լիաէկրան ընդհատումները \n- Միշտ ցուցադրել կարճ ծանուցումները \n\n"<b>"4-րդ աստիճան"</b>" \n- Արգելել լիաէկրան ընդհատումները \n- Միշտ ցուցադրել կարճ ծանուցումները \n\n"<b>"3-րդ աստիճան"</b>" \n- Արգելել լիաէկրան ընդհատումները \n- Արգելել կարճ ծանուցումների ցուցադրումը \n\n"<b>"2-րդ աստիճան"</b>" \n- Արգելել լիաէկրան ընդհատումները \n- Արգելել կարճ ծանուցումների ցուցադրումը \n- Անջատել ձայնը և թրթռումը \n\n"<b>"1-ին աստիճան"</b>" \n- Արգելել լիաէկրան ընդհատումները \n- Արգելել կարճ ծանուցումների ցուցադրումը \n- Անջատել ձայնը և թրթռումը \n- Չցուցադրել կողպէկրանում և կարգավիճակի գոտում \n- Ցուցադրել ծանուցումների ցանկի ներքևում \n\n"<b>"0-րդ աստիճան"</b>\n"- Արգելափակել հավելվածի բոլոր ծանուցումները"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Ծանուցումներ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Այս ծանուցումներն այլևս չեք ստանա։"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Այս ծանուցումներն այլևս չեք ստանա"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ծանուցման կատեգորիաներ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Այս հավելվածը ծանուցման կատեգորիաներ չունի"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-hy/strings_tv.xml b/packages/SystemUI/res/values-hy/strings_tv.xml
index 6274cd3..ac7711b 100644
--- a/packages/SystemUI/res/values-hy/strings_tv.xml
+++ b/packages/SystemUI/res/values-hy/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Նկարը նկարի մեջ"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Առանց վերնագրի ծրագիր)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Փակել PIP-ն"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Լիէկրան"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index f7e3054..6269a8b 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Nonaktif"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Dengan kontrol notifikasi daya, Anda dapt menyetel level kepentingan notifikasi aplikasi dari 0 sampai 5. \n\n"<b>"Level 5"</b>" \n- Muncul di atas daftar notifikasi \n- Izinkan interupsi layar penuh \n- Selalu intip pesan \n\n"<b>"Level 4"</b>" \n- Jangan interupsi layar penuh \n- Selalu intip pesan \n\n"<b>"Level 3"</b>" \n- Jangan interupsi layar penuh \n- Tak pernah intip pesan \n\n"<b>"Level 2"</b>" \n- Jangan interupsi layar penuh \n- Tak pernah intip pesan \n- Tanpa suara dan getaran \n\n"<b>"Level 1"</b>" \n- Jangan interupsi layar penuh \n- Tak pernah intip pesan \n- Tanpa suara atau getaran \n- Sembunyikan dari layar kunci dan bilah status \n- Muncul di bawah daftar notifikasi \n\n"<b>"Level 0"</b>" \n- Blokir semua notifikasi dari aplikasi"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifikasi"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Anda tidak akan mendapatkan notifikasi ini lagi."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Anda tidak akan mendapatkan notifikasi ini lagi"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> kategori notifikasi"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Aplikasi ini tidak memiliki kategori notifikasi"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
@@ -644,7 +644,7 @@
     <item msgid="1545641631806817203">"Papan klip"</item>
     <item msgid="5742013440802239414">"Kode tombol"</item>
     <item msgid="8802889973626281575">"Pengalih keyboard"</item>
-    <item msgid="8175437057325747277">"Tidak Ada"</item>
+    <item msgid="8175437057325747277">"Tidak ada"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Biasa"</item>
@@ -734,7 +734,7 @@
     <string name="lockscreen_shortcut_right" msgid="3328683699505226536">"Pintasan kanan"</string>
     <string name="lockscreen_unlock_left" msgid="2043092136246951985">"Pintasan kiri juga membuka kunci"</string>
     <string name="lockscreen_unlock_right" msgid="1529992940510318775">"Pintasan kanan juga membuka kunci"</string>
-    <string name="lockscreen_none" msgid="4783896034844841821">"Tidak Ada"</string>
+    <string name="lockscreen_none" msgid="4783896034844841821">"Tidak ada"</string>
     <string name="tuner_launch_app" msgid="1527264114781925348">"Luncurkan <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="tuner_other_apps" msgid="4726596850501162493">"Aplikasi lainnya"</string>
     <string name="tuner_circle" msgid="2340998864056901350">"Lingkaran"</string>
diff --git a/packages/SystemUI/res/values-in/strings_tv.xml b/packages/SystemUI/res/values-in/strings_tv.xml
index eacaeb6..ca3b32f 100644
--- a/packages/SystemUI/res/values-in/strings_tv.xml
+++ b/packages/SystemUI/res/values-in/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Gambar-dalam-Gambar"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program tanpa judul)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Tutup PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Layar penuh"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 0dd6d12..94366bc 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Slökkt"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Með orkutilkynningastýringum geturðu stillt mikilvægi frá 0 upp í 5 fyrir tilkynningar forrita. \n\n"<b>"Stig 5"</b>" \n- Sýna efst á tilkynningalista \n- Leyfa truflun þegar birt er á öllum skjánum \n- Kíkja alltaf \n\n"<b>"Stig 4"</b>" \n- Hindra truflun við birtingu á öllum skjánum \n- Kíkja alltaf \n\n"<b>"Stig 3"</b>" \n- Hindra truflun við birtingu á öllum skjánum \n- Kíkja aldrei \n\n"<b>"Stig 2"</b>" \n- Hindra truflun við birtingu á öllum skjánum \n- Kíkja aldrei \n- Slökkva á hljóði og titringi \n\n"<b>"Stig 1"</b>" \n- Hindra truflun við birtingu á öllum skjánum \n- Kíkja aldrei \n- Slökkva á hljóði og titringi \n- Fela á lásskjá og stöðustiku \n- Sýna neðst á tilkynningalista \n\n"<b>"Stig 0"</b>" \n- Setja allar tilkynningar frá forriti á bannlista"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Tilkynningar"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Þú færð þessar tilkynningar ekki framar."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Þú færð þessar tilkynningar ekki framar"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> tilkynningaflokkar"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Þetta forrit er ekki með tilkynningaflokka"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-is/strings_tv.xml b/packages/SystemUI/res/values-is/strings_tv.xml
index de001e0..2727548 100644
--- a/packages/SystemUI/res/values-is/strings_tv.xml
+++ b/packages/SystemUI/res/values-is/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Mynd í mynd"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Efni án titils)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Loka mynd í mynd"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Allur skjárinn"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 6d53bd0..4d0e205 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Off"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"I controlli di gestione delle notifiche ti consentono di impostare un livello di importanza compreso tra 0 e 5 per le notifiche di un\'app. \n\n"<b>"Livello 5"</b>" \n- Mostra in cima all\'elenco di notifiche \n- Consenti l\'interruzione a schermo intero \n- Visualizza sempre \n\n"<b>"Livello 4"</b>" \n- Impedisci l\'interruzione a schermo intero \n- Visualizza sempre \n\n"<b>"Livello 3"</b>" \n- Impedisci l\'interruzione a schermo intero \n- Non visualizzare mai \n\n"<b>"Livello 2"</b>" \n- Impedisci l\'interruzione a schermo intero \n- Non visualizzare mai \n- Non emettere mai suoni e vibrazioni \n\n"<b>"Livello 1"</b>" \n- Impedisci l\'interruzione a schermo intero \n- Non visualizzare mai \n- Non emettere mai suoni e vibrazioni \n- Nascondi da schermata di blocco e barra di stato \n- Mostra in fondo all\'elenco di notifiche \n\n"<b>"Livello 0"</b>" \n- Blocca tutte le notifiche dell\'app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifiche"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Non riceverai più queste notifiche."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Non riceverai più queste notifiche"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorie di notifica"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Questa app non ha categorie di notifica"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-it/strings_tv.xml b/packages/SystemUI/res/values-it/strings_tv.xml
index 66b74e4..629e306 100644
--- a/packages/SystemUI/res/values-it/strings_tv.xml
+++ b/packages/SystemUI/res/values-it/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Picture-in-Picture"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Programma senza titolo)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Chiudi PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Schermo intero"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index f009a14..d0170908 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -552,7 +552,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"כבוי"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"בעזרת פקדים של הודעות הפעלה, תוכל להגדיר רמת חשיבות מ-0 עד 5 להודעות אפליקציה. \n\n"<b>"רמה 5"</b>" \n- הצג בראש רשימת ההודעות \n- אפשר הפרעה במסך מלא \n- תמיד אפשר הצצה \n\n"<b>"רמה 4"</b>" \n- מנע הפרעה במסך מלא \n- תמיד אפשר הצצה \n\n"<b>"רמה 3"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n\n"<b>"רמה 2"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n- אף פעם אל תאפשר קול ורטט \n\n"<b>"רמה 1"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n- אף פעם אל תאפשר קול ורטט \n- הסתר ממסך הנעילה ומשורת הסטטוס \n- הצג בתחתית רשימת ההודעות \n\n"<b>"רמה 0"</b>" \n- חסום את כל ההודעות מהאפליקציה"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"הודעות"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"לא תקבל את ההודעות האלה יותר."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"לא תקבל את ההודעות האלה יותר"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> קטגוריות של התראות"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"האפליקציה הזו לא תומכת בקטגוריות של הודעות"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-iw/strings_tv.xml b/packages/SystemUI/res/values-iw/strings_tv.xml
index 9bc189b..b460bb7 100644
--- a/packages/SystemUI/res/values-iw/strings_tv.xml
+++ b/packages/SystemUI/res/values-iw/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"תמונה בתוך תמונה"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(תוכנית ללא כותרת)"</string>
     <string name="pip_close" msgid="3480680679023423574">"‏סגור PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"מסך מלא"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 9f63e38..e8d8ee2 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"OFF"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"電源通知管理では、アプリの通知の重要度をレベル 0~5 で設定できます。\n\n"<b>"レベル 5"</b>" \n- 通知リストの一番上に表示する \n- 全画面表示を許可する \n- 常にポップアップする \n\n"<b>"レベル 4"</b>" \n- 全画面表示しない \n- 常にポップアップする \n\n"<b>"レベル 3"</b>" \n- 全画面表示しない \n- ポップアップしない \n\n"<b>"レベル 2"</b>" \n- 全画面表示しない \n- ポップアップしない \n- 音やバイブレーションを使用しない \n\n"<b>"レベル 1"</b>" \n- 全画面表示しない \n- ポップアップしない \n- 音やバイブレーションを使用しない \n- ロック画面やステータスバーに表示しない \n- 通知リストの一番下に表示する \n\n"<b>"レベル 0"</b>" \n- アプリからのすべての通知をブロックする"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"今後、この通知は配信されません。"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"今後、この通知は配信されません"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> 個の通知カテゴリ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"このアプリでは通知カテゴリが設定されていません"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-ja/strings_tv.xml b/packages/SystemUI/res/values-ja/strings_tv.xml
index d249326..134bb18 100644
--- a/packages/SystemUI/res/values-ja/strings_tv.xml
+++ b/packages/SystemUI/res/values-ja/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"PIP"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(無題の番組)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP を閉じる"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"全画面表示"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 3bb07cd..2da6462 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"გამორთული"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"შეტყობინებების მართვის საშუალებების მეშვეობით, შეგიძლიათ განსაზღვროთ აპის შეტყობინებების მნიშვნელობის დონე 0-დან 5-მდე დიაპაზონში. \n\n"<b>"დონე 5"</b>" \n— შეტყობინებათა სიის თავში ჩვენება \n— სრულეკრანიანი რეჟიმის შეფერხების დაშვება \n— ეკრანზე ყოველთვის გამოჩენა \n\n"<b>"დონე 4"</b>" \n— სრულეკრანიანი რეჟიმის შეფერხების აღკვეთა \n— ეკრანზე ყოველთვის გამოჩენა \n\n"<b>"დონე 3"</b>" \n— სრულეკრანიანი რეჟიმის შეფერხების აღკვეთა \n— ეკრანზე გამოჩენის აღკვეთა \n\n"<b>"დონე 2"</b>" \n— სრულეკრანიანი რეჟიმის შეფერხების აღკვეთა \n— ეკრანზე გამოჩენის აღკვეთა \n— ხმისა და ვიბრაციის აღკვეთა \n\n"<b>"დონე 1"</b>" \n— სრულეკრანიანი რეჟიმის შეფერხების აღკვეთა \n— ეკრანზე გამოჩენის აღკვეთა \n— ხმისა და ვიბრაციის აღკვეთა \n— ჩაკეტილი ეკრანიდან და სტატუსის ზოლიდან დამალვა \n— შეტყობინებათა სიის ბოლოში ჩვენება \n\n"<b>"დონე 0"</b>" \n— აპის ყველა შეტყობინების დაბლოკვა"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"შეტყობინებები"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"ამ შეტყობინებებს აღარ მიიღებთ."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"ამ შეტყობინებებს აღარ მიიღებთ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"შეტყობინებების <xliff:g id="NUMBER">%d</xliff:g> კატეგორია"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ამ აპს შეტყობინებების კატეგორიები არ აქვს"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-ka/strings_tv.xml b/packages/SystemUI/res/values-ka/strings_tv.xml
index 18931cc..1a97590 100644
--- a/packages/SystemUI/res/values-ka/strings_tv.xml
+++ b/packages/SystemUI/res/values-ka/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"სურათი სურათში"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(პროგრამის სათაურის გარეშე)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP-ის დახურვა"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"სრულ ეკრანზე"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 44d7bd8..54f376c 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Өшірулі"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Қуат хабарландыруының басқару элементтерімен қолданбаның хабарландырулары үшін 0-ден бастап 5-ке дейін маңыздылық деңгейін орнатуға болады. \n\n"<b>"5-деңгей"</b>" \n- Хабарландыру тізімінің ең басында көрсету \n- Толық экранға ашылуын рұқсат ету \n- Әрдайым қалқымалы хабарландыру түрінде көрсету \n\n"<b>"4-деңгей"</b>" \n- Толық экранға шығармау \n- Әрдайым қалқымалы хабарландыру түрінде көрсету \n\n"<b>"3-деңгей"</b>" \n- Толық экранға шығармау \n- Ешқашан қалқымалы хабарландыру түрінде көрсетпеу \n\n"<b>"2-деңгей"</b>" \n- Толық экранға шығармау \n- Ешқашан қалқымалы хабарландыру түрінде көрсетпеу \n- Ешқашан дыбыс және діріл шығармау \n\n"<b>"1-деңгей"</b>" \n- Толық экранға шығармау \n- Ешқашан қалқымалы хабарландыру түрінде көрсетпеу \n- Ешқашан дыбыс немесе діріл шығармау \n- Құлыпталған экраннан және күйін көрсету жолағынан жасыру \n- Хабарландыру тізімінің ең астында көрсету \n\n"<b>"0-деңгей"</b>" \n- Қолданбадағы барлық хабарландыруларға тыйым салу"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Хабарландырулар"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Сізге енді бұл хабарландырулар жіберілмейді."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Енді сізге бұл хабарландырулар жіберілмейді"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> хабарландыру санаттары"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Бұл қолданбада хабарландыру санаттары жоқ"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-kk/strings_tv.xml b/packages/SystemUI/res/values-kk/strings_tv.xml
index 6e40b53..305ad2e 100644
--- a/packages/SystemUI/res/values-kk/strings_tv.xml
+++ b/packages/SystemUI/res/values-kk/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Сурет ішіндегі сурет"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Атаусыз бағдарлама)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP жабу"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Толық экран"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index b9aaaeb..d53380e 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"បិទ"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ជាមួយអង្គគ្រប់គ្រងការជូនដំណឹងថាមពល អ្នកអាចកំណត់កម្រិតសំខាន់ពី 0 ទៅ 5 សម្រាប់ការជូនដំណឹងរបស់កម្មវិធី។ \n\n"<b>"កម្រិត 5"</b>" \n- បង្ហាញនៅផ្នែកខាងលើបញ្ជីជូនដំណឹង \n- អនុញ្ញាតការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n\n"<b>"កម្រិត 4"</b>" \n- រារាំងការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n\n"<b>"កម្រិត 3"</b>" \n- រារាំងការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n\n"<b>"កម្រិត 2"</b>" \n- រារាំងការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n- មិនបន្លឺសំឡេង ឬញ័រ \n\n"<b>"កម្រិត 1"</b>" \n- រារាំងការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n- មិនបន្លឺសំឡេង ឬញ័រ \n- លាក់ពីអេក្រង់ចាក់សោ និងរបារស្ថានភាព \n- បង្ហាញនៅផ្នែកខាងក្រោមបញ្ជីជូនដំណឹង \n\n"<b>"កម្រិត 0"</b>" \n- រារាំងការជូនដំណឹងទាំងអស់ពីកម្មវិធី"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"ការ​ជូនដំណឹង"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"អ្នក​នឹង​មិន​ទទួល​បាន​ការ​ជូនដំណឹង​ទាំងនេះ​ទៀត​ទេ។"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"អ្នក​នឹង​មិន​ទទួល​បានការ​ជូនដំណឹង​ទាំងនេះ​ទៀត​ទេ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"ប្រភេទនៃការជូនដំណឹងចំនួន <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"កម្មវិធីនេះ​មិនមាន​ប្រភេទនៃ​ការជូនដំណឹង​ទេ"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-km/strings_tv.xml b/packages/SystemUI/res/values-km/strings_tv.xml
index d0e8289..5da818e 100644
--- a/packages/SystemUI/res/values-km/strings_tv.xml
+++ b/packages/SystemUI/res/values-km/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"រូបភាពក្នុងរូបភាព"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(កម្មវិធី​គ្មានចំណងជើង)"</string>
     <string name="pip_close" msgid="3480680679023423574">"បិទ PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"ពេញអេក្រង់"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 1d32f91..816aa44 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ಆಫ್"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ಪವರ್ ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳ ಮೂಲಕ, ನೀವು ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಅಧಿಸೂಚನೆಗಳನ್ನು 0 ರಿಂದ 5 ರವರೆಗಿನ ಹಂತಗಳ ಪ್ರಾಮುಖ್ಯತೆಯನ್ನು ಹೊಂದಿಸಬಹುದು. \n\n"<b>"ಹಂತ 5"</b>" \n- ಮೇಲಿನ ಅಧಿಸೂಚನೆ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ಅನುಮತಿಸಿ \n- ಯಾವಾಗಲು ಇಣುಕು ನೋಟ \n\n"<b>"ಹಂತ 4"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಯಾವಾಗಲು ಇಣುಕು ನೋಟ\n\n"<b>"ಹಂತ 3"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n\n"<b>"ಹಂತ 2"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n- ಶಬ್ದ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಎಂದಿಗೂ ಮಾಡಬೇಡಿ \n\n"<b>"ಹಂತ 1"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n- ಶಬ್ದ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಎಂದಿಗೂ ಮಾಡಬೇಡಿ \n- ಸ್ಥಿತಿ ಪಟ್ಟಿ ಮತ್ತು ಲಾಕ್ ಪರದೆಯಿಂದ ಮರೆಮಾಡಿ \n- ಕೆಳಗಿನ ಅಧಿಸೂಚನೆ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ \n\n"<b>"ಹಂತ 0"</b>" \n- ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ನಿರ್ಬಂಧಿಸಿ"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"ಅಧಿಸೂಚನೆಗಳು"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"ನೀವು ಇನ್ನು ಮುಂದೆ ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಪಡೆಯುವುದಿಲ್ಲ."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"ನೀವು ಇನ್ನು ಮುಂದೆ ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಪಡೆಯುವುದಿಲ್ಲ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ಅಧಿಸೂಚನೆ ವರ್ಗಗಳು"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಅಧಿಸೂಚನೆ ವರ್ಗಗಳನ್ನು ಹೊಂದಿಲ್ಲ"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-kn/strings_tv.xml b/packages/SystemUI/res/values-kn/strings_tv.xml
index 13514c6..85fde1f 100644
--- a/packages/SystemUI/res/values-kn/strings_tv.xml
+++ b/packages/SystemUI/res/values-kn/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರ"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(ಶೀರ್ಷಿಕೆ ರಹಿತ ಕಾರ್ಯಕ್ರಮ)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP ಮುಚ್ಚಿ"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"ಪೂರ್ಣ ಪರದೆ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 6aa58e6..6b3c329 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"사용 안함"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"전원 알림 컨트롤을 사용하면 앱 알림 관련 중요도를 0부터 5까지로 설정할 수 있습니다. \n\n"<b>"레벨 5"</b>" \n- 알림 목록 상단에 표시 \n- 전체 화면일 경우 알림 표시 허용 \n- 항상 엿보기 표시 \n\n"<b>"레벨 4"</b>" \n- 전체 화면에 알림 표시 금지 \n- 항상 엿보기 표시 \n\n"<b>"레벨 3"</b>" \n- 전체 화면에 알림 표시 금지 \n- 엿보기 표시 안함 \n\n"<b>"레벨 2"</b>" \n- 전체 화면에 알림 표시 금지 \n- 엿보기 표시 안함 \n- 소리나 진동으로 알리지 않음 \n\n"<b>"레벨 1"</b>" \n- 전체 화면에 알림 표시 금지 \n- 엿보기 표시 안함 \n- 소리나 진동으로 알리지 않음 \n- 잠금 화면 및 상태 표시줄에서 숨김 \n- 알림 목록 하단에 표시 \n\n"<b>"레벨 0"</b>" \n- 앱의 모든 알림 차단"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"알림"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"더 이상 다음의 알림을 받지 않습니다."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"더 이상 다음의 알림을 받지 않습니다."</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"알림 카테고리 <xliff:g id="NUMBER">%d</xliff:g>개"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"이 앱에는 알림 카테고리가 없습니다."</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-ko/strings_tv.xml b/packages/SystemUI/res/values-ko/strings_tv.xml
index c147048..7c3d5a4 100644
--- a/packages/SystemUI/res/values-ko/strings_tv.xml
+++ b/packages/SystemUI/res/values-ko/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"PIP 모드"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(제목 없는 프로그램)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP 닫기"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"전체화면"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index d737c26..ca2fb78 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Өчүк"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Бул функциянын жардамы менен ар бир колдонмо үчүн эскертменин маанилүүлүк деңгээлин 0дон 5ке чейин койсоңуз болот. \n\n"<b>"5-деңгээл"</b>" \n- Эскертмелер тизмесинин башында көрсөтүлсүн \n- Эскертмелер толук экранда көрсөтүлсүн \n- Калкып чыгуучу эскертмелерге уруксат берилсин \n\n"<b>"4-деңгээл"</b>" \n- Эскертмелер толук экранда көрсөтүлбөсүн \n- Калкып чыгуучу эскертмелерге уруксат берилсин \n\n"<b>"3-деңгээл"</b>" \n- Эскертмелер толук экранда көрсөтүлбөсүн \n- Калкып чыгуучу эскертмелерге тыюу салынсын \n\n"<b>"2-деңгээл"</b>" \n- Эскертмелер толук экранда көрсөтүлбөсүн \n- Калкып чыгуучу эскертмелерге тыюу салынсын \n- Эч качан добуш чыгып же дирилдебесин \n\n"<b>"1-деңгээл"</b>" \n- Эскертмелер толук экранда көрсөтүлбөсүн \n- Калкып чыгуучу эскертмелерге тыюу салынсын \n- Эч качан добуш чыгып же дирилдебесин \n- Кулпуланган экрандан жана абал тилкесинен жашырылсын \n- Эскертмелер тизмесинин аягында көрсөтүлсүн \n\n"<b>"0-деңгээл"</b>" \n- Колдонмодон алынган бардык эскертмелер бөгөттөлсүн"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Эскертмелер"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Мындан ары бул эскертмелер сизге жөнөтүлбөйт."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Мындан ары бул эскертмелер сизге жөнөтүлбөйт"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Эскертмелердин <xliff:g id="NUMBER">%d</xliff:g> категориясы"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Бул колдонмонун эскертме категориялары жок"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-ky/strings_tv.xml b/packages/SystemUI/res/values-ky/strings_tv.xml
index a095ee2..5687b41 100644
--- a/packages/SystemUI/res/values-ky/strings_tv.xml
+++ b/packages/SystemUI/res/values-ky/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Сүрөт ичиндеги сүрөт"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Аталышы жок программа)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP\'ти жабуу"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Толук экран"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 4d2010a..e59fcac 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ປິດ"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ດ້ວຍການຄວບຄຸມການແຈ້ງເຕືອນ, ທ່ານສາມາດຕັ້ງລະດັບຄວາມສຳຄັນຈາກ 0 ຮອດ 5 ໃຫ້ກັບການແຈ້ງເຕືອນແອັບໃດໜຶ່ງໄດ້. \n\n"<b>"ລະດັບ 5"</b>" \n- ສະແດງຢູ່ເທິງສຸດຂອງລາຍການແຈ້ງເຕືອນ \n- ອະນຸຍາດໃຫ້ຂັດຈັງຫວະຕອນເປີດເຕັມຈໍ \n- ແນມເບິ່ງທຸກເທື່ອ \n\n"<b>"ລະດັບ 4"</b>" \n- ກັນບໍ່ໃຫ້ຂັດຈັງຫວະຕອນເປີດເຕັມຈໍ \n- ແນມເບິ່ງທຸກເທື່ອ \n\n"<b>"ລະດັບ 3"</b>" \n- ກັນບໍ່ໃຫ້ຂັດຈັງຫວະຕອນເປີດເຕັມຈໍ \n- ບໍ່ແນມເບິ່ງ \n\n"<b>"ລະດັບ 2"</b>" \n- ກັນບໍ່ໃຫ້ຂັດຈັງຫວະຕອນເປີດເຕັມຈໍ \n- ບໍ່ແນມເບິ່ງ \n- ບໍ່ມີສຽງ ແລະ ບໍ່ມີການສັ່ນເຕືອນ \n\n"<b>"ລະດັບ 1"</b>" \n- ກັນບໍ່ໃຫ້ຂັດຈັງຫວະຕອນເປີດເຕັມຈໍ \n- ບໍ່ແນມເບິ່ງ \n- ບໍ່ມີສຽງ ແລະ ບໍ່ມີການສັ່ນເຕືອນ \n- ເຊື່ອງຈາກໜ້າຈໍລັອກ ແລະ ແຖບສະຖານະ \n- ສະແດງຢູ່ລຸ່ມສຸດຂອງລາຍການແຈ້ງເຕືອນ \n\n"<b>"ລະດັບ 0"</b>" \n- ປິດກັ້ນການແຈ້ງເຕືອນທັງໝົດຈາກແອັບ"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"ການແຈ້ງເຕືອນ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"ທ່ານຈະບໍ່ໄດ້ຮັບການແຈ້ງເຕືອນເຫຼົ່ານີ້ອີກຕໍ່ໄປ."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"ທ່ານຈະບໍ່ໄດ້ຮັບການແຈ້ງເຕືອນເຫຼົ່ານີ້ອີກຕໍ່ໄປ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ໝວດໝູ່ການແຈ້ງເຕືອນ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ແອັບນີ້ບໍ່ມີໝວດໝູ່ການແຈ້ງເຕືອນ"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-lo/strings_tv.xml b/packages/SystemUI/res/values-lo/strings_tv.xml
index 5ca9094..65367842 100644
--- a/packages/SystemUI/res/values-lo/strings_tv.xml
+++ b/packages/SystemUI/res/values-lo/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"ສະແດງຜົນຫຼາຍຢ່າງພ້ອມກັນ"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(ໂປຣແກຣມບໍ່ມີຊື່)"</string>
     <string name="pip_close" msgid="3480680679023423574">"ປິດ PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"ເຕັມໜ້າຈໍ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 50f6b6b..2ded45c 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -552,7 +552,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Išjungta"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Naudodami pranešimų valdiklius galite nustatyti programos pranešimų svarbos lygį nuo 0 iki 5. \n\n"<b>"5 lygis"</b>" \n– Rodyti pranešimų sąrašo viršuje \n– Leisti pertraukti, kai veikia viso ekrano režimas \n– Visada rodyti pranešimus \n\n"<b>"4 lygis"</b>" \n– Neleisti pertraukti viso ekrano režimo \n– Visada rodyti pranešimus \n\n"<b>"3 lygis"</b>" \n– Neleisti pertraukti viso ekrano režimo \n– Niekada nerodyti pranešimų \n\n"<b>"2 lygis"</b>" \n– Neleisti pertraukti viso ekrano režimo \n– Niekada nerodyti pranešimų \n– Niekada neleisti garso ir nevibruoti \n\n"<b>"1 lygis"</b>" \n– Neleisti pertraukti viso ekrano režimo \n– Niekada nerodyti pranešimų \n– Niekada neleisti garso ir nevibruoti \n– Slėpti užrakinimo ekrane ir būsenos juostoje \n– Rodyti pranešimų sąrašo apačioje \n\n"<b>"0 lygis"</b>" \n– Blokuoti visus programos pranešimus"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Pranešimai"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Nebegausite šių pranešimų."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Nebegausite šių pranešimų"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Pranešimų kategorijų: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Šioje programoje nėra pranešimų kategorijų"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-lt/strings_tv.xml b/packages/SystemUI/res/values-lt/strings_tv.xml
index 124a7e3..2e6fa58 100644
--- a/packages/SystemUI/res/values-lt/strings_tv.xml
+++ b/packages/SystemUI/res/values-lt/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Vaizdas vaizde"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Programa be pavadinimo)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Uždaryti PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Visas ekranas"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index c997609..68345a4 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Izslēgts"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Izmantojot barošanas paziņojumu vadīklas, varat lietotnes paziņojumiem iestatīt svarīguma līmeni (no 0 līdz 5). \n\n"<b>"5. līmenis"</b>" \n- Tiek rādīts paziņojumu saraksta augšdaļā \n- Tiek atļauta pilnekrāna režīma pārtraukšana \n- Ieskats vienmēr atļauts \n\n"<b>"4. līmenis"</b>" \n- Tiek novērsta pilnekrāna režīma pārtraukšana \n- Ieskats vienmēr atļauts \n\n"<b>"3. līmenis"</b>" \n- Tiek novērsta pilnekrāna režīma pārtraukšana \n- Ieskats nav atļauts \n\n"<b>"2. līmenis"</b>" \n- Tiek novērsta pilnekrāna režīma pārtraukšana \n- Ieskats nav atļauts \n- Nav atļautas skaņas un vibrosignāls \n\n"<b>"1. līmenis"</b>" \n- Tiek novērsta pilnekrāna režīma pārtraukšana \n- Ieskats nav atļauts \n- Nav atļautas skaņas un vibrosignāls \n- Paziņojumi tiek paslēpti bloķēšanas ekrānā un statusa joslā \n- Paziņojumi tiek rādīti paziņojumu saraksta apakšdaļā \n\n"<b>"0. līmenis"</b>" \n- Visi lietotnes paziņojumi tiek bloķēti"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Paziņojumi"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Jūs vairs nesaņemsiet šos paziņojumus."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Jūs vairs nesaņemsiet šos paziņojumus"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> paziņojumu kategorijas"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Paziņojumu kategorijas šajā lietotnē nav pieejamas."</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-lv/strings_tv.xml b/packages/SystemUI/res/values-lv/strings_tv.xml
index ac9b1d6..474fe98 100644
--- a/packages/SystemUI/res/values-lv/strings_tv.xml
+++ b/packages/SystemUI/res/values-lv/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Attēls attēlā"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Programma bez nosaukuma)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Aizvērt PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Pilnekrāna režīms"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 91f7508..2496fe2 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Исклучено"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Со контролите за известувањата за напојување, може да поставите ниво на важност од 0 до 5 за известувањата на која било апликација. \n\n"<b>"Ниво 5"</b>" \n- Прикажувај на врвот на списокот со известувања \n- Дозволи прекин во цел екран \n- Секогаш користи појавување \n\n"<b>"Ниво 4"</b>" \n- Спречи прекин во цел екран \n- Секогаш користи појавување \n\n"<b>"Ниво 3"</b>" \n- Спречи прекин во цел екран \n- Без појавување \n\n"<b>"Ниво 2"</b>" \n- Спречи прекин во цел екран \n- Без појавување \n- Без звук и вибрации \n\n"<b>"Ниво 1"</b>" \n- Спречи прекин во цел екран \n- Без појавување \n- Без звук и вибрации \n- Сокриј од заклучен екран и статусна лента \n- Прикажувај на дното на списокот со известувања \n\n"<b>"Ниво 0"</b>" \n- Блокирај ги сите известувања од апликацијата"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Известувања"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Веќе нема да ги добивате овие известувања."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Веќе нема да ги добивате овие известувања"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> категории известувања"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Апликацијава нема катерии известувања"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-mk/strings_tv.xml b/packages/SystemUI/res/values-mk/strings_tv.xml
index e9772bb..f12368b 100644
--- a/packages/SystemUI/res/values-mk/strings_tv.xml
+++ b/packages/SystemUI/res/values-mk/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Слика во слика"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Програма без наслов)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Затвори PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Цел екран"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 7def7a5..ae59ce2 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ഓഫ്"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"പവർ അറിയിപ്പ് നിയന്ത്രണം ഉപയോഗിച്ച്, ഒരു ആപ്പിനായുള്ള അറിയിപ്പുകൾക്ക് 0 മുതൽ 5 വരെയുള്ള പ്രാധാന്യ ലെവലുകളിലൊന്ന് നിങ്ങൾക്ക് സജ്ജമാക്കാവുന്നതാണ്. \n\n"<b>"ലെവൽ 5"</b>" \n- അറിയിപ്പ് ലിസ്റ്റിന്റെ മുകളിൽ കാണിക്കുക \n- മുഴുവൻ സ്ക്രീൻ തടസ്സം അനുവദിക്കുക \n- എല്ലായ്പ്പോഴും ദൃശ്യമാക്കുക \n\n"<b>"ലെവൽ 4"</b>" \n- മുഴുവൻ സ്ക്രീൻ തടസ്സം തടയുക \n- എല്ലായ്പ്പോഴും ദൃശ്യമാക്കുക \n\n"<b>"ലെവൽ 3"</b>" \n- മുഴുവൻ സ്ക്രീൻ തടസ്സം തടയുക \n- ഒരിക്കലും സൃശ്യമാക്കരുത് \n\n"<b>"ലെവൽ 2"</b>" \n- മുഴുവൻ സ്ക്രീൻ തടസ്സം തടയുക \n- ഒരിക്കലും ദൃശ്യമാക്കരുത് \n- ഒരിക്കലും ശബ്ദവും വൈബ്രേഷനും ഉണ്ടാക്കരുത് \n\n"<b>"ലെവൽ 1"</b>" \n- മുഴുവൻ സ്ക്രീൻ തടസ്സം തടയുക \n- ഒരിക്കലും ദൃശ്യമാക്കരുത് \n- ഒരിക്കലും ശബ്ദവും വൈബ്രേഷനും ഉണ്ടാക്കരുത് \n- ലോക്ക് സ്ക്രീനിൽ നിന്നും സ്റ്റാറ്റസ് ബാറിൽ നിന്നും മറയ്ക്കുക \n- അറിയിപ്പ് ലിസ്റ്റിന്റെ അടിയിൽ കാണിക്കുക \n\n"<b>"ലെവൽ 0"</b>" \n- ആപ്പിൽ നിന്നുള്ള എല്ലാ അറിയിപ്പുകളും ബ്ലോക്കുചെയ്യുക"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"അറിയിപ്പുകൾ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"നിങ്ങൾക്ക് ഈ അറിയിപ്പുകൾ ഇനിയങ്ങോട്ട് ലഭിക്കില്ല."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"നിങ്ങൾക്ക് ഇനി ഈ അറിയിപ്പുകൾ ലഭിക്കില്ല"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> അറിയിപ്പ് വിഭാഗങ്ങൾ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ഈ ആപ്പിന് അറിയിപ്പ് വിഭാഗങ്ങളില്ല"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-ml/strings_tv.xml b/packages/SystemUI/res/values-ml/strings_tv.xml
index 77763b6..1cf0689 100644
--- a/packages/SystemUI/res/values-ml/strings_tv.xml
+++ b/packages/SystemUI/res/values-ml/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"ചിത്രത്തിനുള്ളിൽ ചിത്രം"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(പേരില്ലാത്ത പ്രോഗ്രാം)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP അടയ്ക്കുക"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"പൂര്‍ണ്ണ സ്ക്രീന്‍"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index fcc7903..6e17561 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Идэвхгүй"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Тэжээлийн мэдэгдлийн удирдлагын тусламжтайгаар та апп-н мэдэгдэлд 0-5 хүртэлх ач холбогдлын түвшин тогтоох боломжтой. \n\n"<b>"5-р түвшин"</b>" \n- Мэдэгдлийн жагсаалтын хамгийн дээр харуулна \n- Бүтэн дэлгэцэд саад болно \n- Дэлгэцэд тогтмол гарч ирнэ \n\n"<b>"4-р түвшин"</b>" \n- Бүтэн дэлгэцэд саад болохоос сэргийлнэ \n- Дэлгэцэд тогтмол гарч ирнэ \n\n"<b>"3-р түвшин"</b>" \n- Бүтэн дэлгэцэд саад болохоос сэргийлнэ \n- Дэлгэцэд хэзээ ч гарч ирэхгүй \n\n"<b>"2-р түвшин"</b>" \n- Бүтэн дэлгэцэд саад болохоос сэргийлнэ \n- Дэлгэцэд хэзээ ч гарч ирэхгүй \n- Дуу болон чичиргээ хэзээ ч гаргахгүй \n\n"<b>"1-р түвшин"</b>" \n- Бүтэн дэлгэцэд саад болохоос сэргийлнэ \n- Дэлгэцэд хэзээ ч гарч ирэхгүй \n- Дуу болон чичиргээ хэзээ ч гаргахгүй \n- Түгжигдсэн дэлгэц болон статусын самбараас нууна \n- Мэдэгдлийн жагсаалтын доор харуулна \n\n"<b>"0-р түвшин"</b>" \n- Энэ апп-н бүх мэдэгдлийг блоклоно"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Мэдэгдэл"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ta цаашид мэдэгдэл авахгүй."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ta цаашид эдгээр мэдэгдлийг авахгүй"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> мэдэгдлийн ангилал"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Энэ апп-д мэдэгдлийн категори алга"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-mn/strings_tv.xml b/packages/SystemUI/res/values-mn/strings_tv.xml
index 2a591f0..bbc94c8 100644
--- a/packages/SystemUI/res/values-mn/strings_tv.xml
+++ b/packages/SystemUI/res/values-mn/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Зураг-доторх-Зураг"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Гарчиггүй хөтөлбөр)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP-г хаах"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Бүтэн дэлгэц"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 8ded3da..9fc8132 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"बंद"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"पॉवर सूचना नियंत्रणांसह, आपण अॅपच्या सूचनांसाठी महत्त्व स्तर 0 ते 5 पर्यंत सेट करू शकता. \n\n"<b>"स्तर 5"</b>" \n- सूचना सूचीच्या शीर्षस्थानी दर्शवा \n- पूर्ण स्क्रीन व्यत्ययास अनुमती द्या \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 4"</b>" \n- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 3"</b>" \n- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n\n"<b>"स्तर 2"</b>" \n- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा कंपन करू नका \n\n"<b>"स्तर 1"</b>" \n- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा कंपन करू नका \n- लॉक स्क्रीन आणि स्टेटस बार मधून लपवा \n- सूचना सूचीच्या तळाशी दर्शवा \n\n"<b>"स्तर 0"</b>" \n- अॅपमधील सर्व सूचना अवरोधित करा"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"सूचना"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"आपल्याला यापुढे या सूचना प्राप्त होणार नाहीत."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"तुम्हाला यापुढे या सूचना प्राप्त होणार नाहीत"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> सूचना श्रेण्या"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"या अ‍ॅपला सूचना श्रेण्या नाहीत"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-mr/strings_tv.xml b/packages/SystemUI/res/values-mr/strings_tv.xml
index 8d1fc5c..aac2d5e 100644
--- a/packages/SystemUI/res/values-mr/strings_tv.xml
+++ b/packages/SystemUI/res/values-mr/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"चित्रा-मध्‍ये-चित्र"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(शीर्षक नसलेला कार्यक्रम)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP बंद करा"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"पूर्ण स्क्रीन"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 2fe3b4d..d1b0d1b 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Mati"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Dengan kawalan pemberitahuan berkuasa, anda boleh menetapkan tahap kepentingan dari 0 hingga 5 untuk pemberitahuan apl. \n\n"<b>"Tahap 5"</b>" \n- Tunjukkan pada bahagian atas senarai pemberitahuan \n- Benarkan gangguan skrin penuh \n- Sentiasa intai \n\n"<b>"Tahap 4"</b>" \n- Halang gangguan skrin penuh \n- Sentiasa intai \n\n"<b>"Tahap 3"</b>" \n- Halang gangguan skrin penuh \n- Jangan intai \n\n"<b>"Tahap 2"</b>" \n- Halang gangguan skrin penuh \n- Jangan intai \n- Jangan berbunyi dan bergetar \n\n"<b>"Tahap 1"</b>" \n- Halang gangguan skrin penuh \n- Jangan intai \n- Jangan berbunyi atau bergetar \n- Sembunyikan daripada skrin kunci dan bar status \n- Tunjukkan di bahagian bawah senarai pemberitahuan \n\n"<b>"Tahap 0"</b>" \n- Sekat semua pemberitahuan daripada apl"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Pemberitahuan"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Anda tidak akan menerima pemberitahuan ini lagi."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Anda tidak akan menerima pemberitahuan ini lagi"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> kategori pemberitahuan"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Apl ini tiada kategori pemberitahuan"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-ms/strings_tv.xml b/packages/SystemUI/res/values-ms/strings_tv.xml
index 0899da2..110ddca 100644
--- a/packages/SystemUI/res/values-ms/strings_tv.xml
+++ b/packages/SystemUI/res/values-ms/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Gambar dalam Gambar"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program tiada tajuk)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Tutup PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Skrin penuh"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index fe5a0e0..f355880 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ပိတ်ပါ"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ပါဝါအကြောင်းကြားချက် ထိန်းချုပ်မှုများကိုအသုံးပြုပြီး အက်ပ်တစ်ခု၏ အကြောင်းကြားချက် အရေးပါမှု ၀ မှ ၅ အထိသတ်မှတ်ပေးနိုင်သည်။ \n\n"<b>"အဆင့် ၅"</b>" \n- အကြောင်းကြားချက်စာရင်း၏ ထိပ်ဆုံးတွင် ပြသည် \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်းကို ခွင့်ပြုသည် \n- အမြဲတမ်း ခေတ္တပြပါမည် \n\n"<b>"အဆင့် ၄"</b>" \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်း မရှိစေရန် ကာကွယ်ပေးသည် \n- အမြဲတမ်း ခေတ္တပြပါမည် \n\n"<b>"အဆင့် ၃"</b>" \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်း မရှိစေရန် ကာကွယ်ပေးသည် \n- ဘယ်တော့မှ ခေတ္တပြခြင်း မရှိပါ \n\n"<b>"အဆင့် ၂"</b>" \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်း မရှိစေရန် ကာကွယ်ပေးသည် \n- ဘယ်တော့မှ ခေတ္တပြခြင်း မရှိပါ \n- အသံမြည်ခြင်းနှင့် တုန်ခါခြင်းများ ဘယ်တော့မှ မပြုလုပ်ပါ \n\n"<b>"အဆင့် ၁"</b>" \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်း မရှိစေရန် ကာကွယ်ပေးသည် \n- ဘယ်တော့မှ ခေတ္တပြခြင်း မရှိပါ \n- အသံမြည်ခြင်းနှင့် တုန်ခါခြင်းများ ဘယ်တော့မှ မပြုလုပ်ပါ \n- လော့ခ်ချထားသည့် မျက်နှာပြင်နှင့် အခြေအနေဘားတန်းတို့တွင် မပြပါ \n- အကြောင်းကြားချက်စာရင်း အောက်ဆုံးတွင်ပြသည် \n\n"<b>"အဆင့် ၀"</b>" \n- အက်ပ်မှ အကြောင်းကြားချက်များ အားလုံးကို ပိတ်ဆို့သည်"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"အကြောင်းကြားချက်များ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"သင်သည် ဤအကြောင်းကြားချက်များကို လက်ခံရရှိတော့မည် မဟုတ်ပါ။"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"သင်သည် ဤအကြောင်းကြားချက်များကို နောက်ထပ် လက်ခံရရှိတော့မည် မဟုတ်ပါ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"အကြောင်းကြားချက် အမျိုးအစား <xliff:g id="NUMBER">%d</xliff:g> ခု"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ဤအက်ပ်တွင် အကြောင်းကြားချက် အမျိုးအစားများ မရှိပါ"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-my/strings_tv.xml b/packages/SystemUI/res/values-my/strings_tv.xml
index f5d53aa..346e553 100644
--- a/packages/SystemUI/res/values-my/strings_tv.xml
+++ b/packages/SystemUI/res/values-my/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"တစ်ခုပေါ်တစ်ခု ထပ်၍ ဖွင့်ခြင်း"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(ခေါင်းစဉ်မဲ့ အစီအစဉ်)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP ကိုပိတ်ပါ"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"မျက်နှာပြင် အပြည့်"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 9715ac6..3dc0440 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Av"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Med effektive varselinnstillinger kan du angi viktighetsnivåer fra 0 til 5 for appvarsler. \n\n"<b>"Nivå 5"</b>" \n– Vis øverst på varsellisten \n– Tillat forstyrrelser ved fullskjermmodus \n– Vis alltid raskt \n\n"<b>"Nivå 4"</b>" \n– Forhindre forstyrrelser ved fullskjermmodus \n– Vis alltid raskt \n\n"<b>"Nivå 3"</b>" \n– Forhindre forstyrrelser ved fullskjermmodus \n– Vis aldri raskt \n\n"<b>"Nivå 2"</b>" \n– Forhindre forstyrrelser ved fullskjermmodus \n– Vis aldri fort \n– Tillat aldri lyder eller vibrering \n\n"<b>"Nivå 1"</b>" \n– Forhindre forstyrrelser ved fullskjermmodus \n– Vis aldri raskt \n– Tillat aldri lyder eller vibrering \n– Skjul fra låseskjermen og statusfeltet \n– Vis nederst på varsellisten \n\n"<b>"Nivå 0"</b>" \n– Blokkér alle varsler fra appen"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Varsler"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Du får ikke disse varslene lenger."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Du får ikke disse varslene lenger"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> varselkategorier"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Denne appen har ikke varselkategorier"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
@@ -701,7 +701,7 @@
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Det kan hende at appen ikke fungerer med delt skjerm."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Appen støtter ikke delt skjerm."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Appen fungerer kanskje ikke på en sekundær skjerm."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Appen støtter ikke oppstart på sekundære skjermer."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Appen kan ikke kjøres på sekundære skjermer."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Åpne innstillingene."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Åpner hurtiginnstillingene."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Lukk hurtiginnstillingene."</string>
diff --git a/packages/SystemUI/res/values-nb/strings_tv.xml b/packages/SystemUI/res/values-nb/strings_tv.xml
index 74774da..59758dd 100644
--- a/packages/SystemUI/res/values-nb/strings_tv.xml
+++ b/packages/SystemUI/res/values-nb/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Bilde-i-bilde"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program uten tittel)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Lukk PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Fullskjerm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 585ae77..3187809 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"निष्क्रिय"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"सशक्त सूचना नियन्त्रणहरू मार्फत तपाईं अनुप्रयाेगका सूचनाहरूका लागि ० देखि ५ सम्मको महत्व सम्बन्धी स्तर सेट गर्न सक्नुहुन्छ। \n\n"<b>"स्तर ५"</b>" \n- सूचनाको सूचीको माथिल्लो भागमा देखाउने \n- पूर्ण स्क्रिनमा अवरोधका लागि अनुमति दिने \n- सधैँ चियाउने \n\n"<b>"स्तर ४"</b>" \n- पूर्ण स्क्रिनमा अवरोधलाई रोक्ने \n- सधैँ चियाउने \n\n"<b>"स्तर ३"</b>" \n- पूर्ण स्क्रिनमा अवरोधलाई रोक्ने \n- कहिल्यै नचियाउने \n\n"<b>"स्तर २"</b>" \n- पूर्ण स्क्रिनमा अवरोधलाई रोक्ने \n- कहिल्यै नचियाउने \n- कहिल्यै पनि आवाज ननिकाल्ने र कम्पन नगर्ने \n\n"<b>"स्तर १"</b>" \n- पूर्ण स्क्रिनमा अवरोध रोक्ने \n- कहिल्यै नचियाउने \n- कहिल्यै पनि आवाज ननिकाल्ने वा कम्पन नगर्ने \n- लक स्क्रिन र वस्तुस्थिति पट्टीबाट लुकाउने \n- सूचनाको सूचीको तल्लो भागमा देखाउने \n\n"<b>"स्तर ०"</b>" \n- अनुप्रयोगका सबै सूचनाहरूलाई रोक्ने"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"सूचनाहरू"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"तपाईंले अबदेखि यी सूचनाहरू प्राप्त गर्नुहुने छैन।"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"तपाईंले अब उप्रान्त यी सूचनाहरू प्राप्त गर्नुहुने छैन"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> सूचनाका कोटिहरू"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"यस अनुप्रयोगमा सूचना सम्बन्धी कोटीहरू छैनन्"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-ne/strings_tv.xml b/packages/SystemUI/res/values-ne/strings_tv.xml
index 8554a91..2c5c186 100644
--- a/packages/SystemUI/res/values-ne/strings_tv.xml
+++ b/packages/SystemUI/res/values-ne/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"तस्बिरभित्रको तस्बिर"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(शीर्षकविहीन कार्यक्रम)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP लाई बन्द गर्नुहोस्"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"पूर्ण स्क्रिन"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index d9de896..08de58c 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Uit"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Met beheeropties voor meldingen met betrekking tot stroomverbruik kun je een belangrijkheidsniveau van 0 tot 5 instellen voor de meldingen van een app. \n\n"<b>"Niveau 5"</b>" \n- Boven aan de lijst met meldingen weergeven \n- Onderbreking op volledig scherm toestaan \n- Altijd korte weergave \n\n"<b>"Niveau 4"</b>" \n- Geen onderbreking op volledig scherm \n- Altijd korte weergave \n\n"<b>"Niveau 3"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n\n"<b>"Niveau 2"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n- Nooit geluid laten horen of trillen \n\n"<b>"Niveau 1"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n- Nooit geluid laten horen of trillen \n- Verbergen op vergrendelingsscherm en statusbalk \n- Onder aan de lijst met meldingen weergeven \n\n"<b>"Niveau 0"</b>" \n- Alle meldingen van de app blokkeren"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Meldingen"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Je ontvangt deze meldingen niet meer."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Je ontvangt deze meldingen niet meer"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> meldingscategorieën"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Deze app heeft geen meldingscategorieën"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-nl/strings_tv.xml b/packages/SystemUI/res/values-nl/strings_tv.xml
index 17c6270..fae484f 100644
--- a/packages/SystemUI/res/values-nl/strings_tv.xml
+++ b/packages/SystemUI/res/values-nl/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Beeld-in-beeld"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Naamloos programma)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP sluiten"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Volledig scherm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 9c54aff..dd56b6e 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ਬੰਦ"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ਪਾਵਰ ਸੂਚਨਾ ਕੰਟਰੋਲਾਂ ਨਾਲ, ਤੁਸੀਂ ਕਿਸੇ ਐਪ ਦੀਆਂ ਸੂਚਨਾਵਾਂ ਲਈ ਮਹੱਤਤਾ ਪੱਧਰ ਨੂੰ 0 ਤੋਂ 5 ਤੱਕ ਸੈੱਟ ਕਰ ਸਕਦੇ ਹੋ। \n\n"<b>"ਪੱਧਰ 5"</b>" \n- ਸੂਚਨਾ ਸੂਚੀ ਦੇ ਸਿਖਰ \'ਤੇ ਵਿਖਾਓ \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਦੀ ਆਗਿਆ ਦਿਓ \n- ਹਮੇਸ਼ਾਂ ਝਲਕ ਵਿਖਾਓ \n\n"<b>"ਪੱਧਰ 4"</b>" \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਨੂੰ ਰੋਕੋ \n- ਹਮੇਸ਼ਾਂ ਝਲਕ ਵਿਖਾਓ \n\n"<b>"ਪੱਧਰ 3"</b>" \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਨੂੰ ਰੋਕੋ \n- ਕਦੇ ਝਲਕ ਨਾ ਵਿਖਾਓ \n\n"<b>"ਪੱਧਰ 2"</b>" \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਰੋਕੋ \n- ਕਦੇ ਝਲਕ ਨਾ ਵਿਖਾਓ \n- ਕਦੇ ਵੀ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਾ ਕਰੋ \n\n"<b>"ਪੱੱਧਰ 1"</b>" \n- ਪੂਰੀ ਸਕ੍ਰੀਨ ਰੁਕਾਵਟ ਨੂੰ ਰੋਕੋ \n- ਕਦੇ ਝਲਕ ਨਾ ਵਿਖਾਓ \n- ਕਦੇ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਾ ਕਰੋ \n- ਲੌਕ ਸਕ੍ਰੀਨ ਅਤੇ ਸਥਿਤੀ ਪੱਟੀ ਤੋਂ ਲੁਕਾਓ \n- ਸੂਚਨਾ ਸੂਚੀ ਦੇ ਹੇਠਾਂ ਵਿਖਾਓ \n\n"<b>"ਪੱਧਰ 0"</b>" \n- ਐਪ ਤੋਂ ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬਲੌਕ ਕਰੋ"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"ਸੂਚਨਾਵਾਂ"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"ਤੁਸੀਂ ਹੁਣ ਇਹ ਸੂਚਨਾਵਾਂ ਪ੍ਰਾਪਤ ਨਹੀਂ ਕਰੋਂਗੇ।"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"ਤੁਹਾਨੂੰ ਹੁਣ ਇਹ ਸੂਚਨਾਵਾਂ ਪ੍ਰਾਪਤ ਨਹੀਂ ਹੋਣਗੀਆਂ"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ਸੂਚਨਾ ਸ਼੍ਰੇਣੀਆਂ"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ਇਸ ਐਪ ਵਿੱਚ ਸੂਚਨਾ ਸ਼੍ਰੇਣੀਆਂ ਨਹੀਂ ਹਨ"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
@@ -700,7 +700,7 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> ਸੂਚਨਾ: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ।"</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ।"</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇ \'ਤੇ ਕੰਮ ਨਾ ਕਰ ਸਕੇ।"</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇ \'ਤੇ ਕੰਮ ਨਾ ਕਰੇ।"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇਆਂ \'ਤੇ ਲਾਂਚ ਕਰਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ।"</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ।"</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਨੂੰ ਖੋਲ੍ਹੋ।"</string>
diff --git a/packages/SystemUI/res/values-pa/strings_tv.xml b/packages/SystemUI/res/values-pa/strings_tv.xml
index b6d9759..245fc44 100644
--- a/packages/SystemUI/res/values-pa/strings_tv.xml
+++ b/packages/SystemUI/res/values-pa/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"ਤਸਵੀਰ-ਵਿੱਚ-ਤਸਵੀਰ"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(ਸਿਰਲੇਖ-ਰਹਿਤ ਪ੍ਰੋਗਰਾਮ)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP ਬੰਦ ਕਰੋ"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"ਪੂਰੀ ਸਕ੍ਰੀਨ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index c23d0d0..02ad8ca 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -552,7 +552,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Wył."</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Dzięki zaawansowanym ustawieniom możesz określić poziom ważności powiadomień z aplikacji w skali od 0 do 5. \n\n"<b>"Poziom 5"</b>" \n– Pokazuj u góry listy powiadomień \n– Zezwalaj na powiadomienia na pełnym ekranie \n– Zawsze pokazuj podgląd \n\n"<b>"Poziom 4"</b>" \n– Wyłącz powiadomienia na pełnym ekranie \n– Zawsze pokazuj podgląd \n\n"<b>"Poziom 3"</b>" \n– Wyłącz powiadomienia na pełnym ekranie \n– Nigdy nie pokazuj podglądu \n\n"<b>"Poziom 2"</b>" \n– Wyłącz powiadomienia na pełnym ekranie \n– Nigdy nie pokazuj podglądu \n– NIgdy nie powiadamiaj dźwiękiem ani wibracjami \n\n"<b>"Poziom 1"</b>" \n– Wyłącz powiadomienia na pełnym ekranie \n– Nigdy nie pokazuj podglądu \n– NIgdy nie powiadamiaj dźwiękiem ani wibracjami \n– Ukrywaj na ekranie blokady i pasku stanu \n– Pokazuj u dołu listy powiadomień \n\n"<b>"Poziom 0"</b>" \n– Blokuj wszystkie powiadomienia aplikacji"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Powiadomienia"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Nie będziesz już otrzymywać tych powiadomień."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Nie będziesz już otrzymywać tych powiadomień"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Kategorie powiadomień: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ta aplikacja nie ma kategorii powiadomień"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-pl/strings_tv.xml b/packages/SystemUI/res/values-pl/strings_tv.xml
index 1148efd..7e0afd9 100644
--- a/packages/SystemUI/res/values-pl/strings_tv.xml
+++ b/packages/SystemUI/res/values-pl/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Obraz w obrazie"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program bez tytułu)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Zamknij PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Pełny ekran"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 4e712d7..66d0b27 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desativado"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Com controles de ativação de notificações, é possível definir o nível de importância de 0 a 5 para as notificações de um app. \n\n"<b>"Nível 5"</b>" \n- Exibir na parte superior da lista de notificações \n- Permitir interrupção em tela cheia \n- Sempre exibir \n\n"<b>"Nível 4"</b>" \n- Impedir interrupções em tela cheia \n- Sempre exibir \n\n"<b>"Nível 3"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n\n"<b>"Nível 2"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n- Nunca emitir som ou vibrar \n\n"<b>"Nível 1"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n- Nunca emitir som ou vibrar \n- Ocultar da tela de bloqueio e barra de status \n- Exibir na parte inferior da lista de notificações \n\n"<b>"Nível 0"</b>" \n- Bloquear todas as notificações do app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificações"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Você deixará de receber essas notificações."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Você deixará de receber essas notificações"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorias de notificação"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Este app não tem categorias de notificação"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
index b55275f..7bcb965 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Picture-in-picture"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(programa sem título)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Fechar PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Tela cheia"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 5db30bb..822a0c0 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desativado"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Com os controlos de notificações do consumo de energia, pode definir um nível de importância de 0 a 5 para as notificações de aplicações. \n\n"<b>"Nível 5"</b>" \n- Mostrar no início da lista de notificações \n- Permitir a interrupção do ecrã inteiro \n- Aparecer rapidamente sempre \n\n"<b>"Nível 4"</b>" \n- Impedir a interrupção do ecrã inteiro \n- Aparecer rapidamente sempre\n\n"<b>"Nível 3"</b>" \n- Impedir a interrupção do ecrã inteiro \n- Nunca aparecer rapidamente \n\n"<b>"Nível 2"</b>" \n- Impedir a interrupção do ecrã inteiro \n- Nunca aparecer rapidamente \n- Nunca tocar nem vibrar \n\n"<b>"Nível 1"</b>" \n- Impedir a interrupção do ecrã inteiro \n- Nunca aparecer rapidamente \n- Nunca tocar nem vibrar \n- Ocultar do ecrã de bloqueio e da barra de estado \n- Mostrar no fim da lista de notificações \n\n"<b>"Nível 0"</b>" \n- Bloquear todas as notificações da aplicação"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificações"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Já não recebe estas notificações."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Deixará de receber estas notificações"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorias de notificação"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Esta aplicação não tem categorias de notificação"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
index 915e22f..a621877 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Imagem na imagem"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Sem título do programa)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Fechar PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Ecrã inteiro"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 4e712d7..66d0b27 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Desativado"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Com controles de ativação de notificações, é possível definir o nível de importância de 0 a 5 para as notificações de um app. \n\n"<b>"Nível 5"</b>" \n- Exibir na parte superior da lista de notificações \n- Permitir interrupção em tela cheia \n- Sempre exibir \n\n"<b>"Nível 4"</b>" \n- Impedir interrupções em tela cheia \n- Sempre exibir \n\n"<b>"Nível 3"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n\n"<b>"Nível 2"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n- Nunca emitir som ou vibrar \n\n"<b>"Nível 1"</b>" \n- Impedir interrupções em tela cheia \n- Nunca exibir \n- Nunca emitir som ou vibrar \n- Ocultar da tela de bloqueio e barra de status \n- Exibir na parte inferior da lista de notificações \n\n"<b>"Nível 0"</b>" \n- Bloquear todas as notificações do app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificações"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Você deixará de receber essas notificações."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Você deixará de receber essas notificações"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorias de notificação"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Este app não tem categorias de notificação"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-pt/strings_tv.xml b/packages/SystemUI/res/values-pt/strings_tv.xml
index b55275f..7bcb965 100644
--- a/packages/SystemUI/res/values-pt/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Picture-in-picture"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(programa sem título)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Fechar PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Tela cheia"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index bf87937..a04d72d7 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -552,7 +552,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Dezactivate"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Folosind comenzile de gestionare a notificărilor, puteți să setați un nivel de importanță de la 0 la 5 pentru notificările unei aplicații. \n\n"<b>"Nivelul 5"</b>" \n– Se afișează la începutul listei de notificări \n– Se permite întreruperea pe ecranul complet \n– Se afișează întotdeauna scurt \n\n"<b>"Nivelul 4"</b>" \n– Se împiedică întreruperea pe ecranul complet \n– Se afișează întotdeauna scurt \n\n"<b>"Nivelul 3"</b>" \n– Se împiedică întreruperea pe ecranul complet \n– Nu se afișează niciodată scurt \n\n"<b>"Nivelul 2"</b>" \n– Se împiedică întreruperea pe ecranul complet \n– Nu se afișează niciodată scurt \n– Nu se emit sunete și nu vibrează niciodată \n\n"<b>"Nivelul 1"</b>" \n– Se împiedică întreruperea pe ecranul complet \n– Nu se afișează niciodată scurt \n– Nu se emit sunete și nu vibrează niciodată \n– Se ascunde în ecranul de blocare și în bara de stare \n– Se afișează la finalul listei de notificări \n\n"<b>"Nivelul 0"</b>" \n– Se blochează toate notificările din aplicație"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificări"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Nu veți mai primi aceste notificări."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Nu veți mai primi aceste notificări"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> categorii de notificări"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Această aplicație nu are categorii de notificare"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-ro/strings_tv.xml b/packages/SystemUI/res/values-ro/strings_tv.xml
index 048b224..3ca7540 100644
--- a/packages/SystemUI/res/values-ro/strings_tv.xml
+++ b/packages/SystemUI/res/values-ro/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Picture-in-Picture"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program fără titlu)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Închideți PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Ecran complet"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 09e1bcb..35a54d2a 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -554,7 +554,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Отключено"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"С помощью этой функции вы можете устанавливать уровень важности уведомлений от 0 до 5 для каждого приложения.\n\n"<b>"Уровень 5"</b>\n"‒ Помещать уведомления в начало списка.\n‒ Показывать полноэкранные уведомления.\n‒ Показывать всплывающие уведомления.\nУровень 4\n"<b></b>\n"‒ Не показывать полноэкранные уведомления.\n‒ Показывать всплывающие уведомления.\nУровень 3\n"<b></b>\n"‒ Не показывать полноэкранные уведомления.\n‒ Не показывать всплывающие уведомления.\nУровень 2\n"<b></b>\n"‒ Не показывать полноэкранные уведомления.\n‒ Не показывать всплывающие уведомления.\n‒ Не использовать звук и вибрацию.\nУровень 1\n"<b></b>\n"‒ Не показывать полноэкранные уведомления.\n‒ Не показывать всплывающие уведомления.\n‒ Не использовать звук и вибрацию.\n‒ Не показывать на экране блокировки и в строке состояния.\n‒ Помещать уведомления в конец списка.\nУровень 0\n"<b></b>\n"‒ Блокировать все уведомления приложения."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Уведомления"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Вы больше не будете получать эти уведомления."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Вы больше не будете получать эти уведомления"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Категорий оповещений: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"В приложении нет категорий уведомлений"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-ru/strings_tv.xml b/packages/SystemUI/res/values-ru/strings_tv.xml
index 41e24c7..e0c55d1 100644
--- a/packages/SystemUI/res/values-ru/strings_tv.xml
+++ b/packages/SystemUI/res/values-ru/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Картинка в картинке"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Без названия)"</string>
     <string name="pip_close" msgid="3480680679023423574">"\"Кадр в кадре\" – выйти"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Во весь экран"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 5024bfc..4ce15ed 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ක්‍රියාවිරහිතයි"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"බල දැනුම්දීම් පාලන සමගින්, ඔබට යෙදුමක දැනුම්දීම් සඳහා වැදගත්කම 0 සිට 5 දක්වා සැකසිය හැකිය. \n\n"<b>"5 මට්ටම"</b>" \n- දැනුම්දීම් ලැයිස්තුවේ ඉහළින්ම පෙන්වන්න \n- පූර්ණ තිර බාධාවට ඉඩ දෙන්න \n- සැම විට එබී බලන්න \n\n"<b>"4 මට්ටම"</b>" \n- පූර්ණ තිර බාධාව වළක්වන්න \n- සැම විට එබී බලන්න \n\n"<b>"3 මට්ටම"</b>" \n- පූර්ණ තිර බාධාව වළක්වන්න \n- කිසි විටක එබී නොබලන්න \n\n"<b>"2 මට්ටම"</b>" \n- පූර්ණ තිර බාධාව වළක්වන්න \n- කිසි විටක එබී නොබලන්න \n- කිසි විටක හඬ සහ කම්පනය සිදු නොකරන්න \n\n"<b>"1 මට්ටම"</b>" \n- පූර්ණ තිර බාධාව වළක්වන්න \n- කිසි විටක එබී නොබලන්න \n- කිසි විටක හඬ සහ කම්පනය සිදු නොකරන්න \n- අගුලු තිරය සහ තත්ත්ව තීරුව වෙතින් සඟවන්න \n- දැනුම්දීම් ලැයිස්තුවේ පහළින්ම පෙන්වන්න \n\n"<b>"0 මට්ටම"</b>" \n- යෙදුම වෙතින් වන සියලු දැනුම් දීම් සඟවන්න."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"දැනුම් දීම්"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"ඔබ තවදුරටත් මෙම දැනුම්දීම් නොලැබෙනු ඇත."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"ඔබට තවදුරටත් මෙම දැනුම්දීම් නොලැබෙනු ඇත"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"දැනුම්දීම් කාණ්ඩ <xliff:g id="NUMBER">%d</xliff:g>ක්"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"මෙම යෙදුම හට දැනුම්දීම් ප්‍රවර්ග නොමැත"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-si/strings_tv.xml b/packages/SystemUI/res/values-si/strings_tv.xml
index f4178fd..f4f15a3 100644
--- a/packages/SystemUI/res/values-si/strings_tv.xml
+++ b/packages/SystemUI/res/values-si/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"පින්තූරය-තුළ-පින්තූරය"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(මාතෘකාවක් නැති වැඩසටහන)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP වසන්න"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"සම්පූර්ණ තිරය"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 1ef815c..e6fa563 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -554,7 +554,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Vypnuté"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Pomocou ovládacích prvkov zobrazovania upozornení môžete nastaviť pre upozornenia aplikácie úroveň dôležitosti od 0 do 5. \n\n"<b>"Úroveň 5"</b>" \n– Zobrazovať v hornej časti zoznamu upozornení. \n– Povoliť prerušenia na celú obrazovku. \n– Vždy zobrazovať čiastočne. \n\n"<b>"Úroveň 4"</b>" \n– Zabrániť prerušeniam na celú obrazovku. \n– Vždy zobrazovať čiastočne. \n\n"<b>"Úroveň 3"</b>" \n– Zabrániť prerušeniam na celú obrazovku. \n– Nikdy nezobrazovať čiastočne. \n\n"<b>"Úroveň 2"</b>" \n– Zabrániť prerušeniam na celú obrazovku. \n– Nikdy nezobrazovať čiastočne. \n– Nikdy nespúšťať zvuk ani vibrácie. \n\n"<b>"Úroveň 1"</b>" \n– Zabrániť prerušeniam na celú obrazovku. \n– Nikdy nezobrazovať čiastočne. \n– Nikdy nespúšťať zvuk ani vibrácie. \n– Skryť na uzamknutej obrazovke a v stavovom riadku. \n– Zobraziť v dolnej časti zoznamu upozornení. \n\n"<b>"Úroveň 0"</b>" \n– Blokovať všetky upozornenia z aplikácie."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Upozornenia"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Takéto upozornenia už nebudete dostávať."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Tieto upozornenia už nebudete dostávať"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Počet kategórií upozornení: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Táto aplikácia nemá kategórie upozornení"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-sk/strings_tv.xml b/packages/SystemUI/res/values-sk/strings_tv.xml
index 196c6e1..1279ecf 100644
--- a/packages/SystemUI/res/values-sk/strings_tv.xml
+++ b/packages/SystemUI/res/values-sk/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Obraz v obraze"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program bez názvu)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Zavrieť režim PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Celá obrazovka"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 7336185..816aa61 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -554,7 +554,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Izklopljeno"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"S kontrolniki za pomebnost obvestila je mogoče za obvestila aplikacije nastaviti stopnjo pomembnosti od 0 do 5. \n\n"<b>"Stopnja 5"</b>" \n– Prikaz na vrhu seznama obvestil \n– Omogočanje prekinitev v celozaslonskem načinu \n– Vedno prikaži hitre predoglede \n\n"<b>"Stopnja 4"</b>" \n– Preprečevanje prekinitev v celozaslonskem načinu \n– Vedno prikaži hitre predoglede \n\n"<b>"Stopnja 3"</b>" \n– Preprečevanje prekinitev v celozaslonskem načinu \n– Nikoli ne prikaži hitrih predogledov \n\n"<b>"Stopnja 2"</b>" \n– Preprečevanje prekinitev v celozaslonskem načinu \n– Nikoli ne prikaži hitrih predogledov \n– Nikoli ne uporabi zvoka in vibriranja \n\n"<b>"Stopnja 1"</b>" \n– Preprečevanje prekinitev v celozaslonskem načinu \n– Nikoli ne prikaži hitrih predogledov \n– Nikoli ne uporabi zvoka in vibriranja \n– Skrivanje na zaklenjenem zaslonu in v vrstici stanja \n– Prikaz na dnu seznama obvestil \n\n"<b>"Stopnja 0"</b>" \n– Blokiranje vseh obvestil aplikacije"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Obvestila"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Teh obvestil ne boste več prejemali."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Teh obvestil ne boste več prejemali"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Št. kategorij obvestil: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ta aplikacija nima kategorij obvestil"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
@@ -758,8 +758,8 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Posnetki zaslona"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Splošna sporočila"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Shramba"</string>
-    <string name="instant_apps" msgid="6647570248119804907">"Aplikacije brez nameščanja"</string>
-    <string name="instant_apps_message" msgid="8116608994995104836">"Aplikacij brez nameščanja ni treba namestiti."</string>
+    <string name="instant_apps" msgid="6647570248119804907">"Nenamestljive aplikacije"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Nenamestljivih aplikacij ni treba namestiti."</string>
     <string name="app_info" msgid="6856026610594615344">"Podatki o aplikaciji"</string>
     <string name="go_to_web" msgid="1106022723459948514">"Pojdi v splet"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobilni podatki"</string>
diff --git a/packages/SystemUI/res/values-sl/strings_tv.xml b/packages/SystemUI/res/values-sl/strings_tv.xml
index b8423e6..8c2e33d 100644
--- a/packages/SystemUI/res/values-sl/strings_tv.xml
+++ b/packages/SystemUI/res/values-sl/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Slika v sliki"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program brez naslova)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Zapri način PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Celozaslonsko"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index c54ce53..e451efc6 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Joaktiv"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Me kontrollet e njoftimit të energjisë, mund të caktosh një nivel rëndësie nga 0 në 5 për njoftimet e një aplikacioni. \n\n"<b>"Niveli 5"</b>" \n- Shfaq në krye të listës së njoftimeve \n- Lejo ndërprerjen e ekranit të plotë \n- Gjithmonë shfaq shpejt \n\n"<b>"Niveli 4"</b>" \n- Parandalo ndërprerjen e ekranit të plotë \n- Gijthmonë shfaq shpejt \n\n"<b>"Niveli 3"</b>" \n- Parandalo ndërprerjen e ekranit të plotë \n- Asnjëherë mos shfaq shpejt \n\n"<b>"Niveli 2"</b>" \n- Parandalo ndërprerjen e ekranit të plotë \n- Asnjëherë mos shfaq shpejt \n- Asnjëherë mos lësho tingull dhe dridhje \n\n"<b>"Niveli 1"</b>" \n- Parandalo ndërprerjen e ekranit të plotë \n- Asnjëherë mos shfaq shpejt \n- Asnjëherë mos lësho tingull ose dridhje \n- Fshih nga ekrani i kyçjes dhe shiriti i statusit \n- Shfaq në fund të listës së njoftimeve \n\n"<b>"Niveli 0"</b>" \n- Blloko të gjitha njoftimet nga aplikacioni"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Njoftime"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Këto njoftime nuk do t\'i marrësh më."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Këto njoftime nuk do t\'i marrësh më"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> kategori njoftimesh"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ky aplikacion nuk ka kategori njoftimesh"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-sq/strings_tv.xml b/packages/SystemUI/res/values-sq/strings_tv.xml
index 12ab06e..8c76832 100644
--- a/packages/SystemUI/res/values-sq/strings_tv.xml
+++ b/packages/SystemUI/res/values-sq/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Figurë brenda figurës"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Program pa titull)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Mbyll PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Ekrani i plotë"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index e9445ff..2e9005d 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -473,7 +473,7 @@
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Брже добијајте обавештења"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Прегледајте их пре откључавања"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Не, хвала"</string>
-    <string name="hidden_notifications_setup" msgid="41079514801976810">"Подеси"</string>
+    <string name="hidden_notifications_setup" msgid="41079514801976810">"Активирај"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="volume_zen_end_now" msgid="3179845345429841822">"Прекини одмах"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Прошири"</string>
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Искључено"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Помоћу напредних контрола за обавештења можете да подесите ниво важности од 0. до 5. за обавештења апликације. \n\n"<b>"5. ниво"</b>" \n– Приказују се у врху листе обавештења \n- Дозволи прекид режима целог екрана \n– Увек завируј \n\n"<b>"4. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Увек завируј \n\n"<b>"3. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n\n"<b>"2. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n– Никада не производи звук или вибрацију \n\n"<b>"1. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n– Никада не производи звук или вибрацију \n– Сакриј на закључаном екрану и статусној траци \n– Приказују се у дну листе обавештења \n\n"<b>"0. ниво"</b>" \n– Блокирај сва обавештења из апликације"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Обавештења"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Више нећете да добијате ова обавештења."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Више нећете добијати ова обавештења"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Категорија обавештења: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ова апликација нема категорије обавештења"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
@@ -739,7 +739,7 @@
     <string name="lockscreen_unlock_left" msgid="2043092136246951985">"И лева пречица откључава"</string>
     <string name="lockscreen_unlock_right" msgid="1529992940510318775">"И десна пречица откључава"</string>
     <string name="lockscreen_none" msgid="4783896034844841821">"Ништа"</string>
-    <string name="tuner_launch_app" msgid="1527264114781925348">"Покретање <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="tuner_launch_app" msgid="1527264114781925348">"Покрени <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="tuner_other_apps" msgid="4726596850501162493">"Друге апликације"</string>
     <string name="tuner_circle" msgid="2340998864056901350">"Круг"</string>
     <string name="tuner_plus" msgid="6792960658533229675">"Плус"</string>
diff --git a/packages/SystemUI/res/values-sr/strings_tv.xml b/packages/SystemUI/res/values-sr/strings_tv.xml
index fac72d4..3e0431f 100644
--- a/packages/SystemUI/res/values-sr/strings_tv.xml
+++ b/packages/SystemUI/res/values-sr/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Слика у слици"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Програм без наслова)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Затвори PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Цео екран"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 99e8f32..09d2cf2 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"På"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Med aviseringsinställningarna kan du ange prioritetsnivå från 0 till 5 för aviseringar från en app. \n\n"<b>"Nivå 5"</b>" \n– Visa högst upp i aviseringslistan\n– Tillåt avbrott i helskärmsläge \n– Snabbvisa alltid \n\n"<b>"Nivå 4"</b>" \n– Tillåt inte avbrott i helskärmsläge \n– Snabbvisa alltid \n\n"<b>"Nivå 3"</b>" \n- Tillåt inte avbrott i helskärmsläge \n– Snabbvisa aldrig \n\n"<b>"Nivå 2"</b>" \n– Tillåt inte avbrott i helskärmsläge \n– Snabbvisa aldrig \n– Aldrig med ljud eller vibration \n\n"<b>"Nivå 1"</b>" \n– Tillåt inte avbrott i helskärmsläge \n– Snabbvisa aldrig \n– Aldrig med ljud eller vibration \n– Visa inte på låsskärmen och i statusfältet \n– Visa längst ned i aviseringslistan \n\n"<b>"Nivå 0"</b>" \n– Blockera alla aviseringar från appen"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Aviseringar"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Inga fler aviseringar av det här slaget visas."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Inga fler aviseringar av det här slaget visas"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> aviseringskategorier"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Det finns inga aviseringskategorier i appen"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-sv/strings_tv.xml b/packages/SystemUI/res/values-sv/strings_tv.xml
index 3c33e8b1..d503e54 100644
--- a/packages/SystemUI/res/values-sv/strings_tv.xml
+++ b/packages/SystemUI/res/values-sv/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Bild-i-bild"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Namnlöst program)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Stäng PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Helskärm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 286eba3..619ac5e 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Imezimwa"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Ukiwa na udhibiti wa arifa, unaweza kuweka kiwango cha umuhimu wa arifa za programu kuanzia 0 hadi 5. \n\n"<b>"Kiwango cha 5"</b>" \n- Onyesha katika sehemu ya juu ya orodha ya arifa \n- Ruhusu ukatizaji wa skrini nzima \n- Ruhusu arifa za kuchungulia kila wakati\n\n"<b>"Kiwango cha 4"</b>" \n- Zuia ukatizaji wa skrini nzima\n- Ruhusu arifa za kuchungulia kila wakati \n\n"<b>"Kiwango cha 3"</b>" \n- Zuia ukatizaji wa skrini nzima\n- Usiruhusu kamwe arifa za kuchungulia\n\n"<b>"Kiwango cha 2"</b>" \n- Zuia ukatizaji wa skrini nzima\n- Usiruhusu kamwe arifa za kuchungulia \n- Usiruhusu kamwe sauti au mtetemo \n\n"<b>"Kiwango cha 1"</b>" \n- Zuia ukatizaji wa skrini nzima \n- Usiruhusu kamwe arifa za kuchungulia \n- Usiruhusu kamwe sauti na mtetemo \n- Usionyeshe skrini iliyofungwa na sehemu ya arifa \n- Onyesha katika sehemu ya chini ya orodha ya arifa \n\n"<b>"Kiwango cha 0"</b>" \n- Zuia arifa zote kutoka programu"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Arifa"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Hutapokea arifa hizi tena."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Hutapokea arifa hizi tena"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Aina <xliff:g id="NUMBER">%d</xliff:g> za arifa"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Programu hii haina aina za arifa"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-sw/strings_tv.xml b/packages/SystemUI/res/values-sw/strings_tv.xml
index 8811959..713a691 100644
--- a/packages/SystemUI/res/values-sw/strings_tv.xml
+++ b/packages/SystemUI/res/values-sw/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Picha ndani ya picha"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Programu isiyo na jina)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Funga PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Skrini nzima"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 6300d8c..3b924eb 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"முடக்கத்தில்"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ஆற்றல்மிக்க அறிவிப்புக் கட்டுப்பாடுகள் மூலம், பயன்பாட்டின் அறிவிப்புகளுக்கு முக்கியத்துவ நிலையை (0-5) அமைக்கலாம். \n\n"<b>"நிலை 5"</b>" \n- அறிவிப்புப் பட்டியலின் மேலே காட்டும் \n- முழுத் திரைக் குறுக்கீட்டை அனுமதிக்கும் \n- எப்போதும் நடப்புத் திரையின் மேல் பகுதியில் அறிவிப்புகளைக் காட்டும் \n\n"<b>"நிலை 4"</b>" \n- முழுத் திரைக் குறுக்கீட்டைத் தடுக்கும் \n- எப்போதும் நடப்புத் திரையின் மேல் பகுதியில் அறிவிப்புகளைக் காட்டும் \n\n"<b>"நிலை 3"</b>" \n- முழுத் திரைக் குறுக்கீட்டைத் தடுக்கும் \n- ஒருபோதும் நடப்புத் திரையின் மேல் பகுதியில் அறிவிப்புகளைக் காட்டாது \n\n"<b>"நிலை 2"</b>" \n- முழுத் திரைக் குறுக்கீட்டைத் தடுக்கும் \n- ஒருபோதும் நடப்புத் திரையின் மேல் பகுதியில் அறிவிப்புகளைக் காட்டாது \n- ஒருபோதும் ஒலி எழுப்பாது, அதிர்வுறாது \n\n"<b>"நிலை 1"</b>" \n- முழுத் திரைக் குறுக்கீட்டைத் தடுக்கும் \n- ஒருபோதும் நடப்புத் திரையின் மேல் பகுதியில் அறிவிப்புகளைக் காட்டாது \n- ஒருபோதும் ஒலி எழுப்பாது அல்லது அதிர்வுறாது \n- பூட்டுத்திரை மற்றும் நிலைப்பட்டியிலிருந்து மறைக்கும் \n- அறிவிப்புகள் பட்டியலின் கீழே காட்டும் \n\n"<b>"நிலை 0"</b>" \n- பயன்பாட்டின் எல்லா அறிவிப்புகளையும் தடுக்கும்"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"அறிவிப்புகள்"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"இந்த அறிவிப்புகளை இனி பெறமாட்டீர்கள்."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"இந்த அறிவிப்புகளை இனி பெறமாட்டீர்கள்"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> அறிவிப்பு வகைகள்"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"இந்தப் பயன்பாட்டில் அறிவிப்பு வகைகள் இல்லை"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-ta/strings_tv.xml b/packages/SystemUI/res/values-ta/strings_tv.xml
index a54bd87..5ddab56 100644
--- a/packages/SystemUI/res/values-ta/strings_tv.xml
+++ b/packages/SystemUI/res/values-ta/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"பிக்ச்சர் இன் பிக்ச்சர்"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(தலைப்பு இல்லை)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIPஐ மூடு"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"முழுத்திரை"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 3900f26..88721ce 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ఆఫ్‌లో ఉన్నాయి"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"పవర్ నోటిఫికేషన్ నియంత్రణలతో, మీరు అనువర్తన నోటిఫికేషన్‌ల కోసం ప్రాముఖ్యత స్థాయిని 0 నుండి 5 వరకు సెట్ చేయవచ్చు. \n\n"<b>"స్థాయి 5"</b>" \n- నోటిఫికేషన్ జాబితా పైభాగంలో చూపబడతాయి \n- పూర్తి స్క్రీన్ అంతరాయం అనుమతించబడుతుంది \n- ఎల్లప్పుడూ త్వరిత వీక్షణ అందించబడుతుంది \n\n"<b>"స్థాయి 4"</b>" \n- పూర్తి స్క్రీన్ అంతరాయం నిరోధించబడుతుంది \n- ఎల్లప్పుడూ త్వరిత వీక్షణ అందించబడుతుంది \n\n"<b>"స్థాయి 3"</b>" \n- పూర్తి స్క్రీన్ అంతరాయం నిరోధించబడుతుంది \n- ఎప్పుడూ త్వరిత వీక్షణ అందించబడదు \n\n"<b>"స్థాయి 2"</b>" \n- పూర్తి స్క్రీన్ అంతరాయం నిరోధించబడుతుంది \n- ఎప్పుడూ త్వరిత వీక్షణ అందించబడదు \n- ఎప్పుడూ శబ్దం మరియు వైబ్రేషన్ చేయవు \n\n"<b>"స్థాయి 1"</b>" \n- పూర్తి స్క్రీన్ అంతరాయం నిరోధించబడుతుంది \n- ఎప్పుడూ త్వరిత వీక్షణ అందించబడదు \n- ఎప్పుడూ శబ్దం లేదా వైబ్రేట్ చేయవు \n- లాక్ స్క్రీన్ మరియు స్థితి పట్టీ నుండి దాచబడతాయి \n- నోటిఫికేషన్ జాబితా దిగువ భాగంలో చూపబడతాయి \n\n"<b>"స్థాయి 0"</b>" \n- అనువర్తనం నుండి అన్ని నోటిఫికేషన్‌లు బ్లాక్ చేయబడతాయి"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"నోటిఫికేషన్‌లు"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"మీరు ఇకపై ఈ నోటిఫికేషన్‌లను పొందరు."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"మీరు ఇకపై ఈ నోటిఫికేషన్‌లను పొందరు"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> నోటిఫికేషన్ వర్గాలు"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"ఈ అనువర్తనానికి నోటిఫికేషన్ వర్గాలు లేవు"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-te/strings_tv.xml b/packages/SystemUI/res/values-te/strings_tv.xml
index 3ead9f6..9f2ea4e 100644
--- a/packages/SystemUI/res/values-te/strings_tv.xml
+++ b/packages/SystemUI/res/values-te/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"చిత్రంలో చిత్రం"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(శీర్షిక లేని ప్రోగ్రామ్)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIPని మూసివేయి"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"పూర్తి స్క్రీన్"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 76d2b8e..aaaae5f 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ปิด"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ส่วนควบคุมการแจ้งเตือนแบบเปิด/ปิดช่วยให้คุณตั้งค่าระดับความสำคัญสำหรับการแจ้งเตือนของแอปได้ตั้งแต่ระดับ 0-5 \n\n"<b>"ระดับ 5"</b>" \n- แสดงที่ด้านบนของรายการแจ้งเตือน \n- อนุญาตให้รบกวนแบบเต็มหน้าจอ \n- อนุญาตให้แสดงชั่วครู่ \n\n"<b>"ระดับ 4"</b>" \n- ป้องกันการรบกวนแบบเต็มหน้าจอ \n- แสดงชั่วครู่เสมอ \n\n"<b>"ระดับ 3"</b>" \n- ป้องกันการรบกวนแบบเต็มหน้าจอ \n- ไม่แสดงชั่วครู่เลย \n\n"<b>"ระดับ 2"</b>" \n- ป้องกันการรบกวนแบบเต็มหน้าจอ \n- ไม่แสดงชั่วครู่เลย \n- ไม่ส่งเสียงหรือสั่นเลย \n\n"<b>"ระดับ 1"</b>" \n- ป้องกันการรบกวนแบบเต็มหน้าจอ \n- ไม่แสดงชั่วครู่เลย \n- ไม่ส่งเสียงหรือสั่นเลย \n- ซ่อนจากหน้าจอล็อกและแถบสถานะ \n- แสดงที่ด้านล่างของรายการแจ้งเตือน \n\n"<b>"ระดับ 0"</b>" \n- บล็อกการแจ้งเตือนทั้งหมดจากแอป"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"การแจ้งเตือน"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"คุณจะไม่ได้รับการแจ้งเตือนเหล่านี้อีก"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"คุณจะไม่ได้รับการแจ้งเตือนเหล่านี้อีก"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"หมวดหมู่การแจ้งเตือน <xliff:g id="NUMBER">%d</xliff:g> หมวด"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"แอปนี้ไม่มีหมวดหมู่การแจ้งเตือน"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-th/strings_tv.xml b/packages/SystemUI/res/values-th/strings_tv.xml
index 22bb321..3a5eba1 100644
--- a/packages/SystemUI/res/values-th/strings_tv.xml
+++ b/packages/SystemUI/res/values-th/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"การแสดงผลหลายแหล่งพร้อมกัน"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(ไม่มีชื่อรายการ)"</string>
     <string name="pip_close" msgid="3480680679023423574">"ปิด PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"เต็มหน้าจอ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 5c4647e..12470c1 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Naka-off"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Sa pamamagitan ng mga kontrol sa notification ng power, magagawa mong itakda ang antas ng kahalagahan ng mga notification ng isang app mula 0 hanggang 5. \n\n"<b>"Antas 5"</b>" \n- Ipakita sa itaas ng listahan ng notification \n- Payagan ang pag-istorbo kapag full screen \n- Palaging sumilip \n\n"<b>"Antas 4"</b>" \n- Pigilan ang pag-istorbo kapag full screen \n- Palaging sumilip \n\n"<b>"Antas 3"</b>" \n- Pigilan ang pag-istorbo kapag full screen \n- Huwag kailanman sumilip \n\n"<b>"Antas 2"</b>" \n- Pigilan ang pag-istorbo kapag full screen \n- Huwag kailanman sumilip \n- Huwag kailanman tumunog o mag-vibrate \n\n"<b>"Antas 1"</b>" \n- Pigilan ang pag-istorbo kapag full screen \n- Huwag kailanman sumilip \n- Huwag kailanman tumunog o mag-vibrate \n- Itago sa lock screen at status bar \n- Ipakita sa ibaba ng listahan ng notification \n\n"<b>"Antas 0"</b>" \n- I-block ang lahat ng notification mula sa app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Mga Notification"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Hindi mo na matatanggap ang mga notification na ito."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Hindi ka na makakatanggap ng ganitong mga notification"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> (na) kategorya ng notification"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Walang kategorya ng notification ang app na ito"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-tl/strings_tv.xml b/packages/SystemUI/res/values-tl/strings_tv.xml
index 4d2f85a..8420c45 100644
--- a/packages/SystemUI/res/values-tl/strings_tv.xml
+++ b/packages/SystemUI/res/values-tl/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Picture-in-Picture"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Walang pamagat na programa)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Isara ang PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 7baae25..a9f6fb5 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Kapalı"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Güç bildirim kontrolleriyle, bir uygulamanın bildirimleri için 0 ile 5 arasında bir önem düzeyi ayarlayabilirsiniz. \n\n"<b>"5. Düzey"</b>" \n- Bildirim listesinin en üstünde gösterilsin \n- Tam ekran kesintisine izin verilsin \n- Ekranda her zaman kısaca belirsin \n\n"<b>"4. Düzey"</b>" \n- Tam ekran kesintisi engellensin \n- Ekranda her zaman kısaca belirsin \n\n"<b>"3. Düzey"</b>" \n- Tam ekran kesintisi engellensin \n- Ekranda hiçbir zaman kısaca belirmesin \n\n"<b>"2. Düzey"</b>" \n- Tam ekran kesintisi engellensin \n- Ekranda hiçbir zaman belirmesin \n- Hiçbir zaman ses çıkarmasın ve titreştirmesin \n\n"<b>"1. Düzey"</b>" \n- Tam ekran kesintisi engellensin \n- Ekranda hiçbir zaman kısaca belirmesin \n- Hiçbir zaman ses çıkarmasın veya titreştirmesin \n- Kilit ekranından ve durum çubuğundan gizlensin \n- Bildirim listesinin en altında gösterilsin \n\n"<b>"0. Düzey"</b>" \n- Uygulamadan gelen tüm bildirimler engellensin"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Bildirimler"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Bu bildirimleri artık almayacaksınız."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Bu bildirimleri artık almayacaksınız"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> bildirim kategorisi"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Bu uygulamanın bildirim kategorisi yok"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-tr/strings_tv.xml b/packages/SystemUI/res/values-tr/strings_tv.xml
index 85b0269..ec2c784 100644
--- a/packages/SystemUI/res/values-tr/strings_tv.xml
+++ b/packages/SystemUI/res/values-tr/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Ekran İçinde Ekran"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Başlıksız program)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP\'yi kapat"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Tam ekran"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 54decf9..05896a5 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -554,7 +554,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Вимк."</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"За допомогою елементів керування сповіщеннями ви можете налаштувати пріоритет сповіщень додатка – від 0 до 5 рівня. \n\n"<b>"Рівень 5"</b>\n"- Показувати сповіщення вгорі списку \n- Виводити на весь екран \n- Завжди показувати короткі сповіщення \n\n"<b>"Рівень 4"</b>\n"- Не виводити на весь екран \n- Завжди показувати короткі сповіщення \n\n"<b>"Рівень 3"</b>\n"- Не виводити на весь екран \n- Не показувати короткі сповіщення \n\n"<b>"Рівень 2"</b>\n"- Не виводити на весь екран \n- Не показувати короткі сповіщення \n- Вимкнути звук і вібросигнал \n\n"<b>"Рівень 1"</b>\n"- Не виводити на весь екран \n- Не показувати короткі сповіщення \n- Вимкнути звук і вібросигнал \n- Не показувати на заблокованому екрані та в рядку стану \n- Показувати сповіщення внизу списку \n\n"<b>"Рівень 0"</b>\n"- Блокувати всі сповіщення з додатка"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Сповіщення"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ви більше не отримуватимете ці сповіщення."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ви більше не отримуватимете ці сповіщення"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"Категорії сповіщень (<xliff:g id="NUMBER">%d</xliff:g>)"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"У цьому додатку немає категорій сповіщень"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-uk/strings_tv.xml b/packages/SystemUI/res/values-uk/strings_tv.xml
index f30155c..af96291 100644
--- a/packages/SystemUI/res/values-uk/strings_tv.xml
+++ b/packages/SystemUI/res/values-uk/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Картинка в картинці"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Програма без назви)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Закрити PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"На весь екран"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 06e99a1..a388478 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"آف"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"پاور اطلاع کنٹرولز کے ساتھ آپ کسی ایپ کی اطلاعات کیلئے 0 سے 5 تک اہمیت کی سطح سیٹ کر سکتے ہیں۔ \n\n"<b>"سطح 5"</b>\n"- اطلاعات کی فہرست کے اوپر دکھائیں \n- پوری اسکرین کی مداخلت کی اجازت دیں \n- ہمیشہ جھانکنا\n\n"<b>"سطح 4"</b>\n"- پوری اسکرین کی مداخلت کو روکیں \n- ہمیشہ جھانکنا\n\n"<b>"سطح 3"</b>\n"- پوری اسکرین کی مداخلت کو روکیں \n- کبھی نہ جھانکنا \n\n"<b>"سطح 2"</b>\n"- پوری اسکرین کی مداخلت کو روکیں \n- کبھی نہ جھانکنا \n- کبھی آواز اور ارتعاش پیدا نہ کرنا \n\n"<b>" سطح 1"</b>\n"- پوری اسکرین کی مداخلت کو روکنا \n- کبھی نہ جھانکنا \n- کبھی بھی آواز یا ارتعاش پیدا نہ کرنا\n- مقفل اسکرین اور اسٹیٹس بار سے چھپانا \n - اطلاع کی فہرست کی نیچے دکھانا \n\n"<b>"سطح 0"</b>\n"- ایپ سے تمام اطلاعات مسدود کریں"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"اطلاعات"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"آپ کو یہ اطلاعات مزید نہیں ملیں گی۔"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"آپ کو یہ اطلاعات مزید نہیں ملیں گی"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"اطلاع کے <xliff:g id="NUMBER">%d</xliff:g> زمرے"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"اس ایپ میں اطلاعاتی زمرے نہیں ہیں"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-ur/strings_tv.xml b/packages/SystemUI/res/values-ur/strings_tv.xml
index 0dec84c..b547bee 100644
--- a/packages/SystemUI/res/values-ur/strings_tv.xml
+++ b/packages/SystemUI/res/values-ur/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"تصویر میں تصویر"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(بلا عنوان پروگرام)"</string>
     <string name="pip_close" msgid="3480680679023423574">"‏PIP بند کریں"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"فُل اسکرین"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 658aeea..451d1de 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"O‘chiq"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Bildirishnomalar uchun kengaytirilgan boshqaruv yordamida ilova bildirishnomalarining muhimlik darajasini (0-5) sozlash mumkin. \n\n"<b>"5-daraja"</b>" \n- Bildirishnomani ro‘yxatning boshida ko‘rsatish \n- To‘liq ekranli bildirishnomalarni ko‘rsatish \n- Qalqib chiquvchi bildirishnomalarni ko‘rsatish \n\n"<b>"4-daraja"</b>" \n- To‘liq ekranli bildirishnomalarni ko‘rsatmaslik \n- Qalqib chiquvchi bildirishnomalarni ko‘rsatish \n\n"<b>"3-daraja"</b>" \n- To‘liq ekranli bildirishnomalarni ko‘rsatmaslik \n- Qalqib chiquvchi bildirishnomalarni ko‘rsatmaslik \n\n"<b>"2-daraja"</b>" \n- To‘liq ekranli bildirishnomalarni ko‘rsatmaslik \n- Qalqib chiquvchi bildirishnomalarni ko‘rsatmaslik \n- Ovoz va tebranishdan foydalanmaslik \n\n"<b>"1-daraja"</b>" \n- To‘liq ekranli bildirishnomalarni ko‘rsatmaslik \n- Qalqib chiquvchi bildirishnomalarni ko‘rsatmaslik \n- Ovoz va tebranishdan foydalanmaslik \n- Ekran qulfi va holat qatorida ko‘rsatmaslik \n- Bildirishnomani ro‘yxatning oxirida ko‘rsatish \n\n"<b>"0-daraja"</b>" \n- Ilovadan keladigan barcha bildirishnomalarni bloklash"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Bildirishnomalar"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ushbu bildirishnomalar endi ko‘rsatilmaydi."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ushbu bildirishnomalar endi ko‘rsatilmaydi"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> ta bildirishnoma turkumi"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Bu ilovada bildirishnomalar turkumi yo‘q"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-uz/strings_tv.xml b/packages/SystemUI/res/values-uz/strings_tv.xml
index efa894a..dc1e1452 100644
--- a/packages/SystemUI/res/values-uz/strings_tv.xml
+++ b/packages/SystemUI/res/values-uz/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Tasvir ustida tasvir"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Nomsiz)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Kadr ichida kadr – chiqish"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"To‘liq ekran"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index e4959fe..0b23a6f 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Tắt"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Với các kiểm soát thông báo nguồn, bạn có thể đặt cấp độ quan trọng từ 0 đến 5 cho các thông báo của ứng dụng. \n\n"<b>"Cấp 5"</b>" \n- Hiển thị ở đầu danh sách thông báo \n- Cho phép gián đoạn ở chế độ toàn màn hình \n- Luôn xem nhanh \n\n"<b>"Cấp 4"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Luôn xem nhanh \n\n"<b>"Cấp 3"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Không bao giờ xem nhanh \n\n"<b>"Cấp 2"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Không bao giờ xem nhanh \n- Không bao giờ có âm báo và rung \n\n"<b>"Cấp 1"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Không bao giờ xem nhanh \n- Không bao giờ có âm báo và rung \n- Ẩn khỏi màn hình khóa và thanh trạng thái \n- Hiển thị ở cuối danh sách thông báo \n\n"<b>"Cấp 0"</b>" \n- Chặn tất cả các thông báo từ ứng dụng"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Thông báo"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Bạn sẽ không nhận được những thông báo này nữa."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Bạn sẽ không nhận được những thông báo này nữa"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> danh mục thông báo"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Ứng dụng này không có loại thông báo"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-vi/strings_tv.xml b/packages/SystemUI/res/values-vi/strings_tv.xml
index 17afa0d..31a1428 100644
--- a/packages/SystemUI/res/values-vi/strings_tv.xml
+++ b/packages/SystemUI/res/values-vi/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Ảnh trong ảnh"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Không có chương trình tiêu đề)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Đóng PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Toàn màn hình"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 96c81c0..e56486c 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"关闭"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"利用高级通知设置,您可以为应用通知设置从 0 级到 5 级的重要程度等级。\n\n"<b>"5 级"</b>" \n- 在通知列表顶部显示 \n- 允许全屏打扰 \n- 一律短暂显示通知 \n\n"<b>"4 级"</b>" \n- 禁止全屏打扰 \n- 一律短暂显示通知 \n\n"<b>"3 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n\n"<b>"2 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n- 一律不发出声音或振动 \n\n"<b>"1 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n- 一律不发出声音或振动 \n- 不在锁定屏幕和状态栏中显示 \n- 在通知列表底部显示 \n\n"<b>"0 级"</b>" \n- 屏蔽应用的所有通知"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"您将不会再收到这类通知。"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"您将不会再收到这类通知"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> 个通知类别"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"此应用没有通知类别"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
index 7b1136f..577186b 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"画中画"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(节目没有标题)"</string>
     <string name="pip_close" msgid="3480680679023423574">"关闭画中画"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"全屏"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index af7f769..8b37751 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -22,7 +22,7 @@
     <string name="app_label" msgid="7164937344850004466">"系統使用者介面"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"清除"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"從清單中移除"</string>
-    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"應用程式資訊"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"應用程式資料"</string>
     <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"您最近的螢幕顯示在這裡"</string>
     <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"關閉最近使用的應用程式"</string>
     <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
@@ -200,7 +200,7 @@
     <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"飛行模式已開啟。"</string>
     <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"飛行模式已關閉。"</string>
     <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"飛行模式已開啟。"</string>
-    <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"開啟「請勿騷擾」,僅限優先。"</string>
+    <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"開啟「請勿騷擾」,只限優先。"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"開啟「請勿騷擾」,完全靜音。"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"開啟「請勿騷擾」,只限鬧鐘。"</string>
     <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"請勿騷擾。"</string>
@@ -269,7 +269,7 @@
     <string name="start_dreams" msgid="5640361424498338327">"螢幕保護程式"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"以太網"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"請勿騷擾"</string>
-    <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"僅限優先"</string>
+    <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"只限優先"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"只限鬧鐘"</string>
     <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"完全靜音"</string>
     <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"藍牙"</string>
@@ -369,7 +369,7 @@
     <string name="camera_hint" msgid="7939688436797157483">"從圖示快速滑動即可使用相機功能"</string>
     <string name="interruption_level_none_with_warning" msgid="5114872171614161084">"完全靜音。這亦將使螢幕閱讀器靜音。"</string>
     <string name="interruption_level_none" msgid="6000083681244492992">"完全靜音"</string>
-    <string name="interruption_level_priority" msgid="6426766465363855505">"僅限優先"</string>
+    <string name="interruption_level_priority" msgid="6426766465363855505">"只限優先"</string>
     <string name="interruption_level_alarms" msgid="5226306993448328896">"只限鬧鐘"</string>
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"完全\n靜音"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"僅限\n優先"</string>
@@ -550,7 +550,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"關閉"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"通知控制項讓您設定應用程式通知的重要性 (0 至 5 級)。\n\n"<b>"第 5 級"</b>" \n- 在通知清單頂部顯示 \n- 允許全螢幕騷擾 \n- 一律顯示通知 \n\n"<b>"第 4 級"</b>" \n- 阻止全螢幕騷擾 \n- 一律顯示通知 \n\n"<b>"第 3 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n\n"<b>"第 2 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n- 永不發出聲響和震動 \n\n"<b>"第 1 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n- 永不發出聲響和震動 \n- 從上鎖畫面和狀態列中隱藏 \n- 在通知清單底部顯示 \n\n"<b>"第 0 級"</b>" \n- 封鎖所有應用程式通知"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"您不會再收到這些通知。"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"您不會再收到這些通知"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> 個通知類別"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"此應用程式沒有通知類別"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
index 13eab22..953d6e4 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"畫中畫"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(沒有標題的節目)"</string>
     <string name="pip_close" msgid="3480680679023423574">"關閉 PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"全螢幕"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 1559d07..0c13b71 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"關閉"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"只要使用電源通知控制項,你就能為應用程式通知設定從 0 到 5 的重要性等級。\n\n"<b>"等級 5"</b>" \n- 顯示在通知清單頂端 \n- 允許全螢幕通知 \n- 一律允許短暫顯示通知 \n\n"<b>"等級 4"</b>" \n- 禁止全螢幕通知 \n- 一律允許短暫顯示通知 \n\n"<b>"等級 3"</b>" \n- 禁止全螢幕通知 \n- 一律不允許短暫顯示通知 \n\n"<b>"等級 2"</b>" \n- 禁止全螢幕通知 \n- 一律不允許短暫顯示通知 \n- 一律不發出音效或震動 \n\n"<b>"等級 1"</b>" \n- 禁止全螢幕通知 \n- 一律不允許短暫顯示通知 \n- 一律不發出音效或震動 \n- 在鎖定畫面和狀態列中隱藏 \n- 顯示在通知清單底端 \n\n"<b>"等級 0"</b>" \n- 封鎖應用程式的所有通知"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"你不會再收到這類通知。"</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"你不會再收到這類通知"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> 個通知類別"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"這個應用程式沒有通知類別"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
index 9634ada..faa9484 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"子母畫面"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(無標題的節目)"</string>
     <string name="pip_close" msgid="3480680679023423574">"關閉子母畫面"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"全螢幕"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 3f0dde6..4851163 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -548,7 +548,7 @@
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"Valiwe"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Ngezilawuli zesaziso zamandla, ungasetha ileveli ebalulekile kusuka ku-0 kuya ku-5 kusuka kuzaziso zohlelo lokusebenza. \n\n"<b>"Ileveli 5"</b>" \n- Ibonisa phezulu kuhlu lwesaziso \n- Vumela ukuphazamiseka kwesikrini esigcwele \n- Ukuhlola njalo \n\n"<b>"Ileveli 4"</b>" \n- Gwema ukuphazamiseka kwesikrini esigcwele \n- Ukuhlola njalo \n\n"<b>"Ileveli 3"</b>" \n- Gwema ukuphazamiseka kwesikrini esigcwele \n- Ukungahloli \n\n"<b>"Ileveli 2"</b>" \n- Gwema ukuphazamiseka kwesikrini esigcwele \n- Ukungahloli \n- Ungenzi umsindo nokudlidliza \n\n"<b>"Ileveli 1"</b>" \n- Gwema ukuphazamiseka kwesikrini esigcwele \n- Ukungahloli \n- Ungenzi umsindo noma ukudlidliza \n- Fihla kusuka kusikrini sokukhiya nebha yesimo \n- Bonisa phansi kohlu lwesaziso \n\n"<b>"Ileveli 0"</b>" \n- Vimbela zonke izaziso kusuka kuhlelo lokusebenza"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Izaziso"</string>
-    <string name="notification_channel_disabled" msgid="5805874247999578073">"Ngeke usathola lezi zaziso."</string>
+    <string name="notification_channel_disabled" msgid="2139193533791840539">"Ngeke usathola izaziso"</string>
     <string name="notification_num_channels" msgid="2048144408999179471">"<xliff:g id="NUMBER">%d</xliff:g> izigaba zesaziso"</string>
     <string name="notification_default_channel_desc" msgid="2506053815870808359">"Lolu hlelo lokusebenza alunazo izigaba zesaziso"</string>
     <plurals name="notification_num_channels_desc" formatted="false" msgid="5492793452274077663">
diff --git a/packages/SystemUI/res/values-zu/strings_tv.xml b/packages/SystemUI/res/values-zu/strings_tv.xml
index 827ec70..26155e4 100644
--- a/packages/SystemUI/res/values-zu/strings_tv.xml
+++ b/packages/SystemUI/res/values-zu/strings_tv.xml
@@ -19,6 +19,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Isithombe-esithombeni"</string>
+    <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Alukho uhlelo lwesihloko)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Vala i-PIP"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Iskrini esigcwele"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 06b945d..ce57bf9 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -124,10 +124,6 @@
     <declare-styleable name="PluginInflateContainer">
         <attr name="viewType" format="string" />
     </declare-styleable>
-    <declare-styleable name="ScrimView">
-        <!-- The initial color for the scrim. -->
-        <attr name="scrimColor" format="color" />
-    </declare-styleable>
 
     <attr name="lightIconTheme" format="reference" />
     <attr name="darkIconTheme" format="reference" />
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 8896e6f..3ef28bd 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -32,7 +32,6 @@
     <color name="qs_detail_button">@*android:color/quaternary_device_default_settings</color>
     <color name="qs_detail_button_white">#B3FFFFFF</color><!-- 70% white -->
     <color name="qs_detail_transition">#66FFFFFF</color>
-    <color name="scrim_behind_color">@android:color/black</color>
     <color name="status_bar_clock_color">#FFFFFFFF</color>
     <color name="qs_user_detail_icon_muted">#FFFFFFFF</color> <!-- not so muted after all -->
     <color name="qs_tile_disabled_color">#9E9E9E</color> <!-- 38% black -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 66476d13..0d777f6 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1195,6 +1195,9 @@
     <!-- Indication on the keyguard that appears when a trust agents unlocks the device. [CHAR LIMIT=40] -->
     <string name="keyguard_indication_trust_granted">Unlocked for <xliff:g id="user_name" example="John Doe">%1$s</xliff:g></string>
 
+    <!-- Indication on the keyguard that appears when a trust agent is active and available. [CHAR LIMIT=40] -->
+    <string name="keyguard_indication_trust_managed"><xliff:g id="trust_agent" example="Smart Lock">%1$s</xliff:g> is running</string>
+
     <!-- Indication on the keyguard that appears when the user disables trust agents until the next time they unlock manually. [CHAR LIMIT=NONE] -->
     <string name="keyguard_indication_trust_disabled">Device will stay locked until you manually unlock</string>
 
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 79db544..5197c95 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -272,6 +272,8 @@
 
         mProviders.put(TunablePaddingService.class, () -> new TunablePaddingService());
 
+        mProviders.put(UiOffloadThread.class, UiOffloadThread::new);
+
         // Put all dependencies above here so the factory can override them if it wants.
         SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
index cdad8ae..44a044b 100644
--- a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
@@ -22,9 +22,6 @@
 
 public interface RecentsComponent {
     void showRecentApps(boolean triggeredFromAltTab, boolean fromHome);
-    void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
-    void toggleRecents();
-    void preloadRecents();
     void showNextAffiliatedTask();
     void showPrevAffiliatedTask();
 
diff --git a/packages/SystemUI/src/com/android/systemui/UiOffloadThread.java b/packages/SystemUI/src/com/android/systemui/UiOffloadThread.java
new file mode 100644
index 0000000..82fd9b3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/UiOffloadThread.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 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
+ */
+
+package com.android.systemui;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * Thread that offloads work from the UI thread but that is still perceptible to the user, so the
+ * priority is the same as the main thread.
+ */
+public class UiOffloadThread {
+
+    private final ExecutorService mExecutorService = Executors.newSingleThreadExecutor();
+
+    public Future<?> submit(Runnable runnable) {
+        return mExecutorService.submit(runnable);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
index 1abea37..a129ace 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
@@ -30,7 +30,10 @@
 import android.view.MotionEvent;
 import android.view.accessibility.AccessibilityManager;
 
+import com.android.systemui.Dependency;
+import com.android.systemui.UiOffloadThread;
 import com.android.systemui.analytics.DataCollector;
+import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.statusbar.StatusBarState;
 
 import java.io.PrintWriter;
@@ -63,6 +66,7 @@
     private final DataCollector mDataCollector;
     private final HumanInteractionClassifier mHumanInteractionClassifier;
     private final AccessibilityManager mAccessibilityManager;
+    private final UiOffloadThread mUiOffloadThread;
 
     private static FalsingManager sInstance = null;
 
@@ -86,6 +90,7 @@
         mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
         mDataCollector = DataCollector.getInstance(mContext);
         mHumanInteractionClassifier = HumanInteractionClassifier.getInstance(mContext);
+        mUiOffloadThread = Dependency.get(UiOffloadThread.class);
         mScreenOn = context.getSystemService(PowerManager.class).isInteractive();
 
         mContext.getContentResolver().registerContentObserver(
@@ -130,7 +135,11 @@
     private void sessionExitpoint(boolean force) {
         if (mSessionActive && (force || !shouldSessionBeActive())) {
             mSessionActive = false;
-            mSensorManager.unregisterListener(this);
+
+            // This can be expensive, and doesn't need to happen on the main thread.
+            mUiOffloadThread.submit(() -> {
+                mSensorManager.unregisterListener(this);
+            });
         }
     }
 
@@ -154,7 +163,11 @@
         for (int sensorType : sensors) {
             Sensor s = mSensorManager.getDefaultSensor(sensorType);
             if (s != null) {
-                mSensorManager.registerListener(this, s, SensorManager.SENSOR_DELAY_GAME);
+
+                // This can be expensive, and doesn't need to happen on the main thread.
+                mUiOffloadThread.submit(() -> {
+                    mSensorManager.registerListener(this, s, SensorManager.SENSOR_DELAY_GAME);
+                });
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java b/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java
index 262d29d..745f312 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java
@@ -17,6 +17,10 @@
 package com.android.systemui.keyguard;
 
 import com.android.internal.policy.IKeyguardDismissCallback;
+import com.android.systemui.Dependency;
+import com.android.systemui.UiOffloadThread;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.misc.SystemServicesProxy;
 
 import java.util.ArrayList;
 
@@ -26,6 +30,7 @@
 public class DismissCallbackRegistry {
 
     private final ArrayList<DismissCallbackWrapper> mDismissCallbacks = new ArrayList<>();
+    private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
 
     public void addCallback(IKeyguardDismissCallback callback) {
         mDismissCallbacks.add(new DismissCallbackWrapper(callback));
@@ -33,14 +38,16 @@
 
     public void notifyDismissCancelled() {
         for (int i = mDismissCallbacks.size() - 1; i >= 0; i--) {
-            mDismissCallbacks.get(i).notifyDismissCancelled();
+            DismissCallbackWrapper callback = mDismissCallbacks.get(i);
+            mUiOffloadThread.submit(callback::notifyDismissCancelled);
         }
         mDismissCallbacks.clear();
     }
 
     public void notifyDismissSucceeded() {
         for (int i = mDismissCallbacks.size() - 1; i >= 0; i--) {
-            mDismissCallbacks.get(i).notifyDismissSucceeded();
+            DismissCallbackWrapper callback = mDismissCallbacks.get(i);
+            mUiOffloadThread.submit(callback::notifyDismissSucceeded);
         }
         mDismissCallbacks.clear();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index f618a2c..b977dd4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -51,6 +51,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.provider.Settings.System;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.util.EventLog;
@@ -76,9 +77,13 @@
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.LatencyTracker;
 import com.android.keyguard.ViewMediatorCallback;
+import com.android.systemui.Dependency;
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIFactory;
+import com.android.systemui.UiOffloadThread;
 import com.android.systemui.classifier.FalsingManager;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.statusbar.phone.FingerprintUnlockController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.ScrimController;
@@ -195,6 +200,7 @@
     private AlarmManager mAlarmManager;
     private AudioManager mAudioManager;
     private StatusBarManager mStatusBarManager;
+    private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
 
     private boolean mSystemReady;
     private boolean mBootCompleted;
@@ -1199,18 +1205,20 @@
             updateInputRestrictedLocked();
         }
     }
+
     private void updateInputRestrictedLocked() {
         boolean inputRestricted = isInputRestricted();
         if (mInputRestricted != inputRestricted) {
             mInputRestricted = inputRestricted;
             int size = mKeyguardStateCallbacks.size();
             for (int i = size - 1; i >= 0; i--) {
+                final IKeyguardStateCallback callback = mKeyguardStateCallbacks.get(i);
                 try {
-                    mKeyguardStateCallbacks.get(i).onInputRestrictedStateChanged(inputRestricted);
+                    callback.onInputRestrictedStateChanged(inputRestricted);
                 } catch (RemoteException e) {
                     Slog.w(TAG, "Failed to call onDeviceProvisioned", e);
                     if (e instanceof DeadObjectException) {
-                        mKeyguardStateCallbacks.remove(i);
+                        mKeyguardStateCallbacks.remove(callback);
                     }
                 }
             }
@@ -1569,9 +1577,11 @@
     private void handleKeyguardDone() {
         Trace.beginSection("KeyguardViewMediator#handleKeyguardDone");
         final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
-        if (mLockPatternUtils.isSecure(currentUser)) {
-            mLockPatternUtils.getDevicePolicyManager().reportKeyguardDismissed(currentUser);
-        }
+        mUiOffloadThread.submit(() -> {
+            if (mLockPatternUtils.isSecure(currentUser)) {
+                mLockPatternUtils.getDevicePolicyManager().reportKeyguardDismissed(currentUser);
+            }
+        });
         if (DEBUG) Log.d(TAG, "handleKeyguardDone");
         synchronized (this) {
             resetKeyguardDonePendingLocked();
@@ -1611,10 +1621,12 @@
                 final UserHandle currentUser = new UserHandle(currentUserId);
                 final UserManager um = (UserManager) mContext.getSystemService(
                         Context.USER_SERVICE);
-                for (int profileId : um.getProfileIdsWithDisabled(currentUser.getIdentifier())) {
-                    mContext.sendBroadcastAsUser(USER_PRESENT_INTENT, UserHandle.of(profileId));
-                }
-                getLockPatternUtils().userPresent(currentUserId);
+                mUiOffloadThread.submit(() -> {
+                    for (int profileId : um.getProfileIdsWithDisabled(currentUser.getIdentifier())) {
+                        mContext.sendBroadcastAsUser(USER_PRESENT_INTENT, UserHandle.of(profileId));
+                    }
+                    getLockPatternUtils().userPresent(currentUserId);
+                });
             } else {
                 mBootSendUserPresent = true;
             }
@@ -1659,11 +1671,18 @@
                 if (mAudioManager == null) return;
                 mUiSoundsStreamType = mAudioManager.getUiSoundsStreamType();
             }
-            // If the stream is muted, don't play the sound
-            if (mAudioManager.isStreamMute(mUiSoundsStreamType)) return;
 
-            mLockSoundStreamId = mLockSounds.play(soundId,
-                    mLockSoundVolume, mLockSoundVolume, 1/*priortiy*/, 0/*loop*/, 1.0f/*rate*/);
+            mUiOffloadThread.submit(() -> {
+                // If the stream is muted, don't play the sound
+                if (mAudioManager.isStreamMute(mUiSoundsStreamType)) return;
+
+                int id = mLockSounds.play(soundId,
+                        mLockSoundVolume, mLockSoundVolume, 1/*priortiy*/, 0/*loop*/, 1.0f/*rate*/);
+                synchronized (this) {
+                    mLockSoundStreamId = id;
+                }
+            });
+
         }
     }
 
@@ -1671,13 +1690,13 @@
         playSound(mTrustedSoundId);
     }
 
-    private void updateActivityLockScreenState() {
-        Trace.beginSection("KeyguardViewMediator#updateActivityLockScreenState");
-        try {
-            ActivityManager.getService().setLockScreenShown(mShowing);
-        } catch (RemoteException e) {
-        }
-        Trace.endSection();
+    private void updateActivityLockScreenState(boolean showing) {
+        mUiOffloadThread.submit(() -> {
+            try {
+                ActivityManager.getService().setLockScreenShown(showing);
+            } catch (RemoteException e) {
+            }
+        });
     }
 
     /**
@@ -1808,11 +1827,11 @@
 
             mWakeAndUnlocking = false;
             setShowingLocked(false);
+            mDismissCallbackRegistry.notifyDismissSucceeded();
             mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration);
             resetKeyguardDonePendingLocked();
             mHideAnimationRun = false;
             adjustStatusBarLocked();
-            mDismissCallbackRegistry.notifyDismissSucceeded();
             sendUserPresentBroadcast();
             mUpdateMonitor.setKeyguardGoingAway(false /* goingAway */);
         }
@@ -1846,7 +1865,10 @@
             }
 
             if (!(mContext instanceof Activity)) {
-                mStatusBarManager.disable(flags);
+                final int finalFlags = flags;
+                mUiOffloadThread.submit(() -> {
+                    mStatusBarManager.disable(finalFlags);
+                });
             }
         }
     }
@@ -2044,18 +2066,21 @@
             mShowing = showing;
             int size = mKeyguardStateCallbacks.size();
             for (int i = size - 1; i >= 0; i--) {
+                IKeyguardStateCallback callback = mKeyguardStateCallbacks.get(i);
                 try {
-                    mKeyguardStateCallbacks.get(i).onShowingStateChanged(showing);
+                    callback.onShowingStateChanged(showing);
                 } catch (RemoteException e) {
                     Slog.w(TAG, "Failed to call onShowingStateChanged", e);
                     if (e instanceof DeadObjectException) {
-                        mKeyguardStateCallbacks.remove(i);
+                        mKeyguardStateCallbacks.remove(callback);
                     }
                 }
             }
             updateInputRestrictedLocked();
-            mTrustManager.reportKeyguardShowingChanged();
-            updateActivityLockScreenState();
+            mUiOffloadThread.submit(() -> {
+                mTrustManager.reportKeyguardShowingChanged();
+            });
+            updateActivityLockScreenState(showing);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index da2d38f..5ca9fa5 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -16,9 +16,11 @@
 
 package com.android.systemui.pip.phone;
 
+import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import android.app.ActivityManager;
+import android.app.ActivityManager.StackInfo;
 import android.app.IActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -33,6 +35,8 @@
 import android.view.WindowManagerGlobal;
 
 import com.android.systemui.pip.BasePipManager;
+import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.component.ExpandPipEvent;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
 import com.android.systemui.statusbar.CommandQueue;
@@ -65,8 +69,8 @@
      */
     TaskStackListener mTaskStackListener = new TaskStackListener() {
         @Override
-        public void onActivityPinned(String packageName) {
-            if (!checkCurrentUserId(false /* debug */)) {
+        public void onActivityPinned(String packageName, int taskId) {
+            if (!checkCurrentUserId(mContext, false /* debug */)) {
                 return;
             }
 
@@ -81,7 +85,7 @@
 
         @Override
         public void onActivityUnpinned() {
-            if (!checkCurrentUserId(false /* debug */)) {
+            if (!checkCurrentUserId(mContext, false /* debug */)) {
                 return;
             }
 
@@ -110,7 +114,7 @@
 
         @Override
         public void onPinnedActivityRestartAttempt(boolean clearedTask) {
-            if (!checkCurrentUserId(false /* debug */)) {
+            if (!checkCurrentUserId(mContext, false /* debug */)) {
                 return;
             }
 
@@ -186,6 +190,7 @@
                 mInputConsumerController);
         mNotificationController = new PipNotificationController(context, mActivityManager,
                 mTouchHandler.getMotionHelper());
+        EventBus.getDefault().register(this);
     }
 
     /**
@@ -196,6 +201,26 @@
     }
 
     /**
+     * Expands the PIP.
+     */
+    public final void onBusEvent(ExpandPipEvent event) {
+        if (event.clearThumbnailWindows) {
+            try {
+                StackInfo stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
+                if (stackInfo != null && stackInfo.taskIds != null) {
+                    SystemServicesProxy ssp = SystemServicesProxy.getInstance(mContext);
+                    for (int taskId : stackInfo.taskIds) {
+                        ssp.cancelThumbnailTransition(taskId);
+                    }
+                }
+            } catch (RemoteException e) {
+                // Do nothing
+            }
+        }
+        mTouchHandler.getMotionHelper().expandPip(false /* skipAnimation */);
+    }
+
+    /**
      * Sent from KEYCODE_WINDOW handler in PhoneWindowManager, to request the menu to be shown.
      */
     public void showPictureInPictureMenu() {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index 766914c..013b9ac 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -63,6 +63,8 @@
 
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
+import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.component.HidePipMenuEvent;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -221,9 +223,9 @@
     protected void onUserLeaveHint() {
         super.onUserLeaveHint();
 
-        // If another task is starting on top of the menu, then finish it so that it can be
+        // If another task is starting on top of the menu, then hide and finish it so that it can be
         // recreated on the top next time it starts
-        finish();
+        hideMenu();
     }
 
     @Override
@@ -231,6 +233,7 @@
         super.onStop();
 
         cancelDelayedFinish();
+        EventBus.getDefault().unregister(this);
     }
 
     @Override
@@ -290,6 +293,19 @@
         // Do nothing
     }
 
+    public final void onBusEvent(HidePipMenuEvent event) {
+        if (mMenuState != MENU_STATE_NONE) {
+            // If the menu is visible in either the closed or full state, then hide the menu and
+            // trigger the animation trigger afterwards
+            event.getAnimationTrigger().increment();
+            hideMenu(() -> {
+                mHandler.post(() -> {
+                    event.getAnimationTrigger().decrement();
+                });
+            }, true /* notifyMenuVisibility */);
+        }
+    }
+
     private void showMenu(int menuState, Rect stackBounds, Rect movementBounds,
             boolean allowMenuTimeout) {
         mAllowMenuTimeout = allowMenuTimeout;
@@ -373,11 +389,16 @@
     private void updateFromIntent(Intent intent) {
         mToControllerMessenger = intent.getParcelableExtra(EXTRA_CONTROLLER_MESSENGER);
         notifyActivityCallback(mMessenger);
+
+        // Register for HidePipMenuEvents once we notify the controller of this activity
+        EventBus.getDefault().register(this);
+
         ParceledListSlice actions = intent.getParcelableExtra(EXTRA_ACTIONS);
         if (actions != null) {
             mActions.clear();
             mActions.addAll(actions.getList());
         }
+
         final int menuState = intent.getIntExtra(EXTRA_MENU_STATE, MENU_STATE_NONE);
         if (menuState != MENU_STATE_NONE) {
             Rect stackBounds = intent.getParcelableExtra(EXTRA_STACK_BOUNDS);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index 5afa53f..e310847 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -27,6 +27,7 @@
 import android.content.pm.ParceledListSlice;
 import android.graphics.Rect;
 import android.os.Bundle;
+import android.os.Debug;
 import android.os.Handler;
 import android.os.Message;
 import android.os.Messenger;
@@ -36,6 +37,9 @@
 import android.view.IWindowManager;
 
 import com.android.systemui.pip.phone.PipMediaController.ActionListener;
+import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.component.HidePipMenuEvent;
+import com.android.systemui.recents.misc.ReferenceCountedTrigger;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -119,6 +123,7 @@
     // The dismiss fraction update is sent frequently, so use a temporary bundle for the message
     private Bundle mTmpDismissFractionData = new Bundle();
 
+    private ReferenceCountedTrigger mOnAttachDecrementTrigger;
     private boolean mStartActivityRequested;
     private Messenger mToActivityMessenger;
     private Messenger mMessenger = new Messenger(new Handler() {
@@ -157,6 +162,10 @@
                 case MESSAGE_UPDATE_ACTIVITY_CALLBACK: {
                     mToActivityMessenger = msg.replyTo;
                     mStartActivityRequested = false;
+                    if (mOnAttachDecrementTrigger != null) {
+                        mOnAttachDecrementTrigger.decrement();
+                        mOnAttachDecrementTrigger = null;
+                    }
                     // Mark the menu as invisible once the activity finishes as well
                     if (mToActivityMessenger == null) {
                         onMenuStateChanged(MENU_STATE_NONE, true /* resize */);
@@ -181,6 +190,8 @@
         mActivityManager = activityManager;
         mMediaController = mediaController;
         mInputConsumerController = inputConsumerController;
+
+        EventBus.getDefault().register(this);
     }
 
     public void onActivityPinned() {
@@ -244,7 +255,9 @@
     public void showMenu(int menuState, Rect stackBounds, Rect movementBounds,
             boolean allowMenuTimeout) {
         if (DEBUG) {
-            Log.d(TAG, "showMenu() hasActivity=" + (mToActivityMessenger != null));
+            Log.d(TAG, "showMenu() state=" + menuState
+                    + " hasActivity=" + (mToActivityMessenger != null)
+                    + " callers=\n" + Debug.getCallers(5, "    "));
         }
         if (mToActivityMessenger != null) {
             Bundle data = new Bundle();
@@ -288,7 +301,9 @@
      */
     public void hideMenu() {
         if (DEBUG) {
-            Log.d(TAG, "hideMenu() hasActivity=" + (mToActivityMessenger != null));
+            Log.d(TAG, "hideMenu() state=" + mMenuState
+                    + " hasActivity=" + (mToActivityMessenger != null)
+                    + " callers=\n" + Debug.getCallers(5, "    "));
         }
         if (mToActivityMessenger != null) {
             Message m = Message.obtain();
@@ -311,13 +326,6 @@
     }
 
     /**
-     * @return the current menu state.
-     */
-    public int getMenuState() {
-        return mMenuState;
-    }
-
-    /**
      * Sets the menu actions to the actions provided by the current PiP activity.
      */
     public void setAppActions(ParceledListSlice appActions) {
@@ -435,6 +443,15 @@
         mMenuState = menuState;
     }
 
+    public final void onBusEvent(HidePipMenuEvent event) {
+        if (mStartActivityRequested) {
+            // If the menu has been start-requested, but not actually started, then we defer the
+            // trigger callback until the menu has started and called back to the controller
+            mOnAttachDecrementTrigger = event.getAnimationTrigger();
+            mOnAttachDecrementTrigger.increment();
+        }
+    }
+
     public void dump(PrintWriter pw, String prefix) {
         final String innerPrefix = prefix + "  ";
         pw.println(prefix + TAG);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index 590e3c6..9fa7ff6 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -34,6 +34,7 @@
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
+import android.os.Debug;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.util.Log;
@@ -54,6 +55,7 @@
 public class PipMotionHelper {
 
     private static final String TAG = "PipMotionHelper";
+    private static final boolean DEBUG = false;
 
     private static final RectEvaluator RECT_EVALUATOR = new RectEvaluator(new Rect());
 
@@ -150,6 +152,10 @@
      * Resizes the pinned stack back to fullscreen.
      */
     void expandPip(boolean skipAnimation) {
+        if (DEBUG) {
+            Log.d(TAG, "expandPip: skipAnimation=" + skipAnimation
+                    + " callers=\n" + Debug.getCallers(5, "    "));
+        }
         cancelAnimations();
         mMenuController.hideMenuWithoutResize();
         mHandler.post(() -> {
@@ -171,6 +177,9 @@
      * Dismisses the pinned stack.
      */
     void dismissPip() {
+        if (DEBUG) {
+            Log.d(TAG, "dismissPip: callers=\n" + Debug.getCallers(5, "    "));
+        }
         cancelAnimations();
         mMenuController.hideMenuWithoutResize();
         mHandler.post(() -> {
@@ -419,6 +428,10 @@
      * Directly resizes the PiP to the given {@param bounds}.
      */
     private void resizePipUnchecked(Rect toBounds) {
+        if (DEBUG) {
+            Log.d(TAG, "resizePipUnchecked: toBounds=" + toBounds
+                    + " callers=\n" + Debug.getCallers(5, "    "));
+        }
         if (!toBounds.equals(mBounds)) {
             mVsyncChoreographer.scheduleAtSfVsync(() -> {
                 try {
@@ -435,6 +448,10 @@
      * Directly resizes the PiP to the given {@param bounds}.
      */
     private void resizeAndAnimatePipUnchecked(Rect toBounds, int duration) {
+        if (DEBUG) {
+            Log.d(TAG, "resizeAndAnimatePipUnchecked: toBounds=" + toBounds
+                    + " duration=" + duration + " callers=\n" + Debug.getCallers(5, "    "));
+        }
         if (!toBounds.equals(mBounds)) {
             mHandler.post(() -> {
                 try {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 199b027..c35fdd5 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -484,14 +484,15 @@
             // Try and restore the PiP to the closest edge, using the saved snap fraction
             // if possible
             if (resize) {
-                // This is a very special case: when the menu is expanded and visible, navigating to
-                // another activity can trigger auto-enter PiP, and if the revealed activity has a
-                // forced rotation set, then the controller will get updated with the new rotation
-                // of the display. However, at the same time, SystemUI will try to hide the menu by
-                // creating an animation to the normal bounds which are now stale.  In such a case
-                // we defer the animation to the normal bounds until after the next
-                // onMovementBoundsChanged() call to get the bounds in the new orientation
                 if (mDeferResizeToNormalBoundsUntilRotation == -1) {
+                    // This is a very special case: when the menu is expanded and visible,
+                    // navigating to another activity can trigger auto-enter PiP, and if the
+                    // revealed activity has a forced rotation set, then the controller will get
+                    // updated with the new rotation of the display. However, at the same time,
+                    // SystemUI will try to hide the menu by creating an animation to the normal
+                    // bounds which are now stale.  In such a case we defer the animation to the
+                    // normal bounds until after the next onMovementBoundsChanged() call to get the
+                    // bounds in the new orientation
                     try {
                         int displayRotation = mPinnedStackController.getDisplayRotation();
                         if (mDisplayRotation != displayRotation) {
@@ -510,6 +511,9 @@
                     mSavedSnapFraction = -1f;
                 }
             } else {
+                // If resizing is not allowed, then the PiP should be frozen until the transition
+                // ends as well
+                setTouchEnabled(false);
                 mSavedSnapFraction = -1f;
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index 198bbe5..6490b33 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -577,7 +577,7 @@
         @Override
         public void onTaskStackChanged() {
             if (DEBUG) Log.d(TAG, "onTaskStackChanged()");
-            if (!checkCurrentUserId(DEBUG)) {
+            if (!checkCurrentUserId(mContext, DEBUG)) {
                 return;
             }
             if (getState() != STATE_NO_PIP) {
@@ -612,9 +612,9 @@
         }
 
         @Override
-        public void onActivityPinned(String packageName) {
+        public void onActivityPinned(String packageName, int taskId) {
             if (DEBUG) Log.d(TAG, "onActivityPinned()");
-            if (!checkCurrentUserId(DEBUG)) {
+            if (!checkCurrentUserId(mContext, DEBUG)) {
                 return;
             }
             StackInfo stackInfo = getPinnedStackInfo();
@@ -641,7 +641,7 @@
         @Override
         public void onPinnedActivityRestartAttempt(boolean clearedTask) {
             if (DEBUG) Log.d(TAG, "onPinnedActivityRestartAttempt()");
-            if (!checkCurrentUserId(DEBUG)) {
+            if (!checkCurrentUserId(mContext, DEBUG)) {
                 return;
             }
             // If PIPed activity is launched again by Launcher or intent, make it fullscreen.
@@ -651,7 +651,7 @@
         @Override
         public void onPinnedStackAnimationEnded() {
             if (DEBUG) Log.d(TAG, "onPinnedStackAnimationEnded()");
-            if (!checkCurrentUserId(DEBUG)) {
+            if (!checkCurrentUserId(mContext, DEBUG)) {
                 return;
             }
             switch (getState()) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 72dd2da..9ba32b3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -19,7 +19,6 @@
 import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS;
 
 import android.app.ActivityManager;
-import android.app.UiModeManager;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -33,7 +32,6 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -41,7 +39,6 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.view.Display;
-import android.view.WindowManager;
 import android.widget.Toast;
 
 import com.android.internal.logging.MetricsLogger;
@@ -60,11 +57,12 @@
 import com.android.systemui.recents.events.component.ShowUserToastEvent;
 import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
 import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.model.HighResThumbnailLoader;
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.CommandQueue;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Set;
@@ -322,16 +320,11 @@
         }
     }
 
-    @Override
-    public void toggleRecentApps() {
-        toggleRecents();
-    }
-
     /**
      * Toggles the Recents activity.
      */
     @Override
-    public void toggleRecents() {
+    public void toggleRecentApps() {
         // Ensure the device has been provisioned before allowing the user to interact with
         // recents
         if (!isUserSetup()) {
@@ -368,7 +361,7 @@
      * Preloads info for the Recents activity.
      */
     @Override
-    public void preloadRecents() {
+    public void preloadRecentApps() {
         // Ensure the device has been provisioned before allowing the user to interact with
         // recents
         if (!isUserSetup()) {
@@ -792,4 +785,10 @@
         }
         return false;
     }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("Recents");
+        pw.println("  currentUserId=" + SystemServicesProxy.getInstance(mContext).getCurrentUser());
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 1b43621..65b7d0e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -62,6 +62,7 @@
 import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent;
 import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
 import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
+import com.android.systemui.recents.events.component.ActivityUnpinnedEvent;
 import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
 import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
 import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
@@ -203,8 +204,12 @@
                                 Recents.getSystemServices().removeTask(task.persistentId);
                             }
                         }
-                        Settings.Secure.putLongForUser(RecentsActivity.this.getContentResolver(),
-                                Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME, currentTime, currentUser);
+                        Recents.getSystemServices().updateOverviewLastStackActiveTimeAsync(
+                                currentTime, currentUser);
+
+                        // Clear the last PiP task time, it's an edge case and we'd rather it
+                        // not relaunch the PiP task if the user double taps
+                        RecentsImpl.clearLastPipTime();
                     }
                 }
             }
@@ -397,6 +402,7 @@
      * Reloads the stack views upon launching Recents.
      */
     private void reloadStackView() {
+
         // If the Recents component has preloaded a load plan, then use that to prevent
         // reconstructing the task stack
         RecentsTaskLoader loader = Recents.getTaskLoader();
@@ -503,28 +509,7 @@
     public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
         super.onMultiWindowModeChanged(isInMultiWindowMode);
 
-        // Reload the task stack completely
-        RecentsConfiguration config = Recents.getConfiguration();
-        RecentsActivityLaunchState launchState = config.getLaunchState();
-        RecentsTaskLoader loader = Recents.getTaskLoader();
-        RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
-        loader.preloadTasks(loadPlan, -1 /* runningTaskId */,
-                false /* includeFrontMostExcludedTask */);
-
-        RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
-        loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
-        loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
-        loader.loadTasks(this, loadPlan, loadOpts);
-
-        TaskStack stack = loadPlan.getTaskStack();
-        int numStackTasks = stack.getStackTaskCount();
-        boolean showDeferredAnimation = numStackTasks > 0;
-
-        EventBus.getDefault().send(new ConfigurationChangedEvent(true /* fromMultiWindow */,
-                false /* fromDeviceOrientationChange */, false /* fromDisplayDensityChange */,
-                numStackTasks > 0));
-        EventBus.getDefault().send(new MultiWindowStateChangedEvent(isInMultiWindowMode,
-                showDeferredAnimation, stack));
+        reloadTaskStack(isInMultiWindowMode, true /* sendConfigChangedEvent */);
     }
 
     @Override
@@ -826,6 +811,41 @@
         mRecentsView.invalidate();
     }
 
+    public final void onBusEvent(final ActivityUnpinnedEvent event) {
+        if (mIsVisible) {
+            // Skip the configuration change event as the PiP activity does not actually affect the
+            // config of recents
+            reloadTaskStack(isInMultiWindowMode(), false /* sendConfigChangedEvent */);
+        }
+    }
+
+    private void reloadTaskStack(boolean isInMultiWindowMode, boolean sendConfigChangedEvent) {
+        // Reload the task stack completely
+        RecentsConfiguration config = Recents.getConfiguration();
+        RecentsActivityLaunchState launchState = config.getLaunchState();
+        RecentsTaskLoader loader = Recents.getTaskLoader();
+        RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
+        loader.preloadTasks(loadPlan, -1 /* runningTaskId */,
+                false /* includeFrontMostExcludedTask */);
+
+        RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
+        loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
+        loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
+        loader.loadTasks(this, loadPlan, loadOpts);
+
+        TaskStack stack = loadPlan.getTaskStack();
+        int numStackTasks = stack.getStackTaskCount();
+        boolean showDeferredAnimation = numStackTasks > 0;
+
+        if (sendConfigChangedEvent) {
+            EventBus.getDefault().send(new ConfigurationChangedEvent(true /* fromMultiWindow */,
+                    false /* fromDeviceOrientationChange */, false /* fromDisplayDensityChange */,
+                    numStackTasks > 0));
+        }
+        EventBus.getDefault().send(new MultiWindowStateChangedEvent(isInMultiWindowMode,
+                showDeferredAnimation, stack));
+    }
+
     @Override
     public boolean onPreDraw() {
         mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
index a7f6b70..5b8ed94 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
@@ -29,6 +29,10 @@
 
     public boolean launchedWithAltTab;
     public boolean launchedFromApp;
+    // Set if the activity that we launched from entered PiP during the transition into Recents
+    public boolean launchedFromPipApp;
+    // Set if the next activity that quick-switch will launch is the PiP activity
+    public boolean launchedWithNextPipApp;
     public boolean launchedFromBlacklistedApp;
     public boolean launchedFromHome;
     public boolean launchedViaDragGesture;
@@ -41,6 +45,8 @@
         launchedFromHome = false;
         launchedFromApp = false;
         launchedFromBlacklistedApp = false;
+        launchedFromPipApp = false;
+        launchedWithNextPipApp = false;
         launchedToTaskId = -1;
         launchedWithAltTab = false;
         launchedViaDragGesture = false;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 2b812a5..e2e9b1b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -35,15 +35,18 @@
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.SystemClock;
-import android.os.UserHandle;
 import android.util.Log;
 import android.util.MutableBoolean;
+import android.util.Pair;
 import android.view.AppTransitionAnimationSpec;
 import android.view.LayoutInflater;
 import android.view.ViewConfiguration;
 import android.view.WindowManager;
 
 import android.widget.Toast;
+
+import com.google.android.collect.Lists;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.policy.DockedDividerUtils;
 import com.android.systemui.R;
@@ -57,6 +60,9 @@
 import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
 import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
 import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
+import com.android.systemui.recents.events.component.ActivityPinnedEvent;
+import com.android.systemui.recents.events.component.ActivityUnpinnedEvent;
+import com.android.systemui.recents.events.component.HidePipMenuEvent;
 import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
 import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
 import com.android.systemui.recents.events.ui.DraggingInRecentsEndedEvent;
@@ -71,6 +77,8 @@
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskGrouping;
 import com.android.systemui.recents.model.TaskStack;
+import com.android.systemui.recents.views.RecentsTransitionHelper;
+import com.android.systemui.recents.views.RecentsTransitionHelper.AppTransitionAnimationSpecsFuture;
 import com.android.systemui.recents.views.TaskStackLayoutAlgorithm;
 import com.android.systemui.recents.views.TaskStackLayoutAlgorithm.VisibilityReport;
 import com.android.systemui.recents.views.TaskStackView;
@@ -111,6 +119,11 @@
 
         @Override
         public void onTaskStackChangedBackground() {
+            // Check this is for the right user
+            if (!checkCurrentUserId(mContext, false /* debug */)) {
+                return;
+            }
+
             // Preloads the next task
             RecentsConfiguration config = Recents.getConfiguration();
             if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) {
@@ -127,6 +140,7 @@
                 // previous one.
                 VisibilityReport visibilityReport;
                 synchronized (mDummyStackView) {
+                    mDummyStackView.getStack().removeAllTasks(false /* notifyStackChanges */);
                     mDummyStackView.setTasks(plan.getTaskStack(), false /* allowNotify */);
                     updateDummyStackViewLayout(plan.getTaskStack(),
                             getWindowRect(null /* windowRectOverride */));
@@ -151,12 +165,46 @@
         }
 
         @Override
+        public void onActivityPinned(String packageName, int taskId) {
+            // Check this is for the right user
+            if (!checkCurrentUserId(mContext, false /* debug */)) {
+                return;
+            }
+
+            // This time needs to be fetched the same way the last active time is fetched in
+            // {@link TaskRecord#touchActiveTime}
+            Recents.getConfiguration().getLaunchState().launchedFromPipApp = true;
+            Recents.getConfiguration().getLaunchState().launchedWithNextPipApp = false;
+            EventBus.getDefault().send(new ActivityPinnedEvent(taskId));
+            consumeInstanceLoadPlan();
+            sLastPipTime = System.currentTimeMillis();
+        }
+
+        @Override
+        public void onActivityUnpinned() {
+            // Check this is for the right user
+            if (!checkCurrentUserId(mContext, false /* debug */)) {
+                return;
+            }
+
+            EventBus.getDefault().send(new ActivityUnpinnedEvent());
+            sLastPipTime = -1;
+        }
+
+        @Override
         public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) {
+            // Check this is for the right user
+            if (!checkCurrentUserId(mContext, false /* debug */)) {
+                return;
+            }
+
             EventBus.getDefault().send(new TaskSnapshotChangedEvent(taskId, snapshot));
         }
     }
 
     protected static RecentsTaskLoadPlan sInstanceLoadPlan;
+    // Stores the last pinned task time
+    protected static long sLastPipTime = -1;
 
     protected Context mContext;
     protected Handler mHandler;
@@ -385,30 +433,34 @@
 
     public void preloadRecents() {
         // Preload only the raw task list into a new load plan (which will be consumed by the
-        // RecentsActivity) only if there is a task to animate to.
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        MutableBoolean isHomeStackVisible = new MutableBoolean(true);
-        if (!ssp.isRecentsActivityVisible(isHomeStackVisible)) {
-            ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
-            if (runningTask == null) {
-                return;
-            }
+        // RecentsActivity) only if there is a task to animate to.  Post this to ensure that we
+        // don't block the touch feedback on the nav bar button which triggers this.
+        mHandler.post(() -> {
+            SystemServicesProxy ssp = Recents.getSystemServices();
+            MutableBoolean isHomeStackVisible = new MutableBoolean(true);
+            if (!ssp.isRecentsActivityVisible(isHomeStackVisible)) {
+                ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
+                if (runningTask == null) {
+                    return;
+                }
 
-            RecentsTaskLoader loader = Recents.getTaskLoader();
-            sInstanceLoadPlan = loader.createLoadPlan(mContext);
-            loader.preloadTasks(sInstanceLoadPlan, runningTask.id, !isHomeStackVisible.value);
-            TaskStack stack = sInstanceLoadPlan.getTaskStack();
-            if (stack.getTaskCount() > 0) {
-                // Only preload the icon (but not the thumbnail since it may not have been taken for
-                // the pausing activity)
-                preloadIcon(runningTask.id);
+                RecentsTaskLoader loader = Recents.getTaskLoader();
+                sInstanceLoadPlan = loader.createLoadPlan(mContext);
+                loader.preloadTasks(sInstanceLoadPlan, runningTask.id, !isHomeStackVisible.value);
+                TaskStack stack = sInstanceLoadPlan.getTaskStack();
+                if (stack.getTaskCount() > 0) {
+                    // Only preload the icon (but not the thumbnail since it may not have been taken
+                    // for the pausing activity)
+                    preloadIcon(runningTask.id);
 
-                // At this point, we don't know anything about the stack state.  So only calculate
-                // the dimensions of the thumbnail that we need for the transition into Recents, but
-                // do not draw it until we construct the activity options when we start Recents
-                updateHeaderBarLayout(stack, null /* window rect override*/);
+                    // At this point, we don't know anything about the stack state.  So only
+                    // calculate the dimensions of the thumbnail that we need for the transition
+                    // into Recents, but do not draw it until we construct the activity options when
+                    // we start Recents
+                    updateHeaderBarLayout(stack, null /* window rect override*/);
+                }
             }
-        }
+        });
     }
 
     public void cancelPreloadingRecents() {
@@ -477,7 +529,8 @@
 
         // Launch the task
         ssp.startActivityFromRecents(
-                mContext, toTask.key, toTask.title, launchOpts, INVALID_STACK_ID);
+                mContext, toTask.key, toTask.title, launchOpts, INVALID_STACK_ID,
+                null /* resultListener */);
     }
 
     /**
@@ -550,7 +603,8 @@
 
         // Launch the task
         ssp.startActivityFromRecents(
-                mContext, toTask.key, toTask.title, launchOpts, INVALID_STACK_ID);
+                mContext, toTask.key, toTask.title, launchOpts, INVALID_STACK_ID,
+                null /* resultListener */);
     }
 
     public void showNextAffiliatedTask() {
@@ -593,6 +647,20 @@
     }
 
     /**
+     * @return the time at which a task last entered picture-in-picture.
+     */
+    public static long getLastPipTime() {
+        return sLastPipTime;
+    }
+
+    /**
+     * Clears the time at which a task last entered picture-in-picture.
+     */
+    public static void clearLastPipTime() {
+        sLastPipTime = -1;
+    }
+
+    /**
      * Reloads all the resources for the current configuration.
      */
     private void reloadResources() {
@@ -632,7 +700,7 @@
             windowRect.bottom -= systemInsets.bottom;
             systemInsets.bottom = 0;
         }
-        calculateWindowStableInsets(systemInsets, windowRect);
+        calculateWindowStableInsets(systemInsets, windowRect, displayRect);
         windowRect.offsetTo(0, 0);
 
         synchronized (mDummyStackView) {
@@ -674,6 +742,7 @@
             updateDummyStackViewLayout(stack, windowRect);
             if (stack != null) {
                 TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm();
+                mDummyStackView.getStack().removeAllTasks(false /* notifyStackChanges */);
                 mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */);
                 // Get the width of a task view so that we know how wide to draw the header bar.
                 if (useGridLayout) {
@@ -721,8 +790,7 @@
      * Given the stable insets and the rect for our window, calculates the insets that affect our
      * window.
      */
-    private void calculateWindowStableInsets(Rect inOutInsets, Rect windowRect) {
-        Rect displayRect = Recents.getSystemServices().getDisplayRect();
+    private void calculateWindowStableInsets(Rect inOutInsets, Rect windowRect, Rect displayRect) {
 
         // Display rect without insets - available app space
         Rect appRect = new Rect(displayRect);
@@ -772,8 +840,9 @@
     /**
      * Creates the activity options for an app->recents transition.
      */
-    private ActivityOptions getThumbnailTransitionActivityOptions(
-            ActivityManager.RunningTaskInfo runningTask, Rect windowOverrideRect) {
+    private Pair<ActivityOptions, AppTransitionAnimationSpecsFuture>
+            getThumbnailTransitionActivityOptions(ActivityManager.RunningTaskInfo runningTask,
+                    Rect windowOverrideRect) {
         if (runningTask != null && runningTask.stackId == FREEFORM_WORKSPACE_STACK_ID) {
             ArrayList<AppTransitionAnimationSpec> specs = new ArrayList<>();
             ArrayList<Task> tasks;
@@ -804,23 +873,27 @@
             }
             AppTransitionAnimationSpec[] specsArray = new AppTransitionAnimationSpec[specs.size()];
             specs.toArray(specsArray);
-            return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
-                    specsArray, mHandler, null, this);
+            return new Pair<>(ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
+                    specsArray, mHandler, null, this), null);
         } else {
             // Update the destination rect
             Task toTask = new Task();
             TaskViewTransform toTransform = getThumbnailTransitionTransform(mDummyStackView, toTask,
                     windowOverrideRect);
-            Bitmap thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform,
-                            mThumbTransitionBitmapCache);
-            if (thumbnail != null) {
-                RectF toTaskRect = toTransform.rect;
-                return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
-                        thumbnail, (int) toTaskRect.left, (int) toTaskRect.top,
-                        (int) toTaskRect.width(), (int) toTaskRect.height(), mHandler, null);
-            }
-            // If both the screenshot and thumbnail fails, then just fall back to the default transition
-            return getUnknownTransitionActivityOptions();
+
+            RectF toTaskRect = toTransform.rect;
+            AppTransitionAnimationSpecsFuture future =
+                    new RecentsTransitionHelper(mContext).getAppTransitionFuture(
+                            () -> {
+                        Rect rect = new Rect();
+                        toTaskRect.round(rect);
+                        Bitmap thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform,
+                                mThumbTransitionBitmapCache);
+                        return Lists.newArrayList(new AppTransitionAnimationSpec(
+                                toTask.key.id, thumbnail, rect));
+                    });
+            return new Pair<>(ActivityOptions.makeMultiThumbFutureAspectScaleAnimation(mContext,
+                    mHandler, future.getFuture(), null, false /* scaleUp */), future);
         }
     }
 
@@ -919,6 +992,9 @@
         launchState.launchedFromHome = !useThumbnailTransition && !mLaunchedWhileDocking;
         launchState.launchedFromApp = useThumbnailTransition || mLaunchedWhileDocking;
         launchState.launchedFromBlacklistedApp = launchState.launchedFromApp && isBlacklisted;
+        launchState.launchedFromPipApp = false;
+        launchState.launchedWithNextPipApp =
+                stack.isNextLaunchTargetPip(RecentsImpl.getLastPipTime());
         launchState.launchedViaDockGesture = mLaunchedWhileDocking;
         launchState.launchedViaDragGesture = mDraggingInRecents;
         launchState.launchedToTaskId = runningTaskId;
@@ -943,30 +1019,31 @@
         launchState.launchedNumVisibleThumbnails = stackVr.numVisibleThumbnails;
 
         if (!animate) {
-            startRecentsActivity(ActivityOptions.makeCustomAnimation(mContext, -1, -1));
+            startRecentsActivity(ActivityOptions.makeCustomAnimation(mContext, -1, -1),
+                    null /* future */);
             return;
         }
 
-        ActivityOptions opts;
+        Pair<ActivityOptions, AppTransitionAnimationSpecsFuture> pair;
         if (isBlacklisted) {
-            opts = getUnknownTransitionActivityOptions();
+            pair = new Pair<>(getUnknownTransitionActivityOptions(), null);
         } else if (useThumbnailTransition) {
             // Try starting with a thumbnail transition
-            opts = getThumbnailTransitionActivityOptions(runningTask, windowOverrideRect);
+            pair = getThumbnailTransitionActivityOptions(runningTask, windowOverrideRect);
         } else {
             // If there is no thumbnail transition, but is launching from home into recents, then
             // use a quick home transition
-            opts = hasRecentTasks
-                ? getHomeTransitionActivityOptions()
-                : getUnknownTransitionActivityOptions();
+            pair = new Pair<>(hasRecentTasks
+                    ? getHomeTransitionActivityOptions()
+                    : getUnknownTransitionActivityOptions(), null);
         }
-        startRecentsActivity(opts);
+        startRecentsActivity(pair.first, pair.second);
         mLastToggleTime = SystemClock.elapsedRealtime();
     }
 
     private Rect getWindowRectOverride(int growTarget) {
         if (growTarget == DividerView.INVALID_RECENTS_GROW_TARGET) {
-            return null;
+            return SystemServicesProxy.getInstance(mContext).getWindowRect();
         }
         Rect result = new Rect();
         Rect displayRect = Recents.getSystemServices().getDisplayRect();
@@ -979,19 +1056,22 @@
     /**
      * Starts the recents activity.
      */
-    private void startRecentsActivity(ActivityOptions opts) {
+    private void startRecentsActivity(ActivityOptions opts,
+            final AppTransitionAnimationSpecsFuture future) {
         Intent intent = new Intent();
         intent.setClassName(RECENTS_PACKAGE, RECENTS_ACTIVITY);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
                 | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
-
-        if (opts != null) {
-            mContext.startActivityAsUser(intent, opts.toBundle(), UserHandle.CURRENT);
-        } else {
-            mContext.startActivityAsUser(intent, UserHandle.CURRENT);
-        }
-        EventBus.getDefault().send(new RecentsActivityStartingEvent());
+        HidePipMenuEvent hideMenuEvent = new HidePipMenuEvent();
+        hideMenuEvent.addPostAnimationCallback(() -> {
+            Recents.getSystemServices().startActivityAsUserAsync(intent, opts);
+            EventBus.getDefault().send(new RecentsActivityStartingEvent());
+            if (future != null) {
+                future.precacheSpecs();
+            }
+        });
+        EventBus.getDefault().send(hideMenuEvent);
     }
 
     /**** OnAnimationFinishedListener Implementation ****/
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java b/packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java
index a737505..d7abb38 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java
@@ -810,6 +810,11 @@
     private void queueEvent(final Event event) {
         ArrayList<EventHandler> eventHandlers = mEventTypeMap.get(event.getClass());
         if (eventHandlers == null) {
+            // This is just an optimization to return early if there are no handlers. However, we
+            // should still ensure that we call pre/post dispatch callbacks so that AnimatedEvents
+            // are still cleaned up correctly if a listener has not been registered to handle them
+            event.onPreDispatch();
+            event.onPostDispatch();
             return;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowEmptyViewEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowEmptyViewEvent.java
new file mode 100644
index 0000000..75bfd7b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowEmptyViewEvent.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 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
+ */
+
+package com.android.systemui.recents.events.activity;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * Sent when the stack should be hidden and the empty view shown.
+ */
+public class ShowEmptyViewEvent extends EventBus.Event {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/ActivityPinnedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/ActivityPinnedEvent.java
new file mode 100644
index 0000000..f4d2fcf
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/component/ActivityPinnedEvent.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.systemui.recents.events.component;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * This is sent when an activity is pinned.
+ */
+public class ActivityPinnedEvent extends EventBus.Event {
+
+    public final int taskId;
+
+    public ActivityPinnedEvent(int taskId) {
+        this.taskId = taskId;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/ActivityUnpinnedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/ActivityUnpinnedEvent.java
new file mode 100644
index 0000000..48c5f0b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/component/ActivityUnpinnedEvent.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.systemui.recents.events.component;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * This is sent when an activity is unpinned.
+ */
+public class ActivityUnpinnedEvent extends EventBus.Event {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/ExpandPipEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/ExpandPipEvent.java
new file mode 100644
index 0000000..8fe4975
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/component/ExpandPipEvent.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.systemui.recents.events.component;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * This is sent when the PiP should be expanded due to being relaunched.
+ */
+public class ExpandPipEvent extends EventBus.Event {
+    public final boolean clearThumbnailWindows = true;
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/HidePipMenuEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/HidePipMenuEvent.java
new file mode 100644
index 0000000..ce4f207
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/component/HidePipMenuEvent.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.systemui.recents.events.component;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * This is sent when the PiP menu should be hidden.
+ */
+public class HidePipMenuEvent extends EventBus.AnimatedEvent {
+    // Simple event
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 8594ec62..cbfa0e5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -26,6 +26,7 @@
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManager.StackInfo;
 import android.app.ActivityManager.TaskSnapshot;
@@ -57,15 +58,18 @@
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.IRemoteCallback;
-import android.os.Looper;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.service.dreams.DreamService;
+import android.service.dreams.IDreamManager;
 import android.util.ArraySet;
 import android.util.IconDrawableFactory;
 import android.util.Log;
@@ -81,14 +85,17 @@
 
 import com.android.internal.app.AssistUtils;
 import com.android.internal.os.BackgroundThread;
-import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.UiOffloadThread;
 import com.android.systemui.pip.tv.PipMenuActivity;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsDebugFlags;
 import com.android.systemui.recents.RecentsImpl;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.ThumbnailData;
+import com.android.systemui.statusbar.policy.UserInfoController;
+import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -96,8 +103,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Random;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 
 /**
  * Acts as a shim around the real system services that we need to access data from, and provides
@@ -127,6 +132,8 @@
     PackageManager mPm;
     IconDrawableFactory mDrawableFactory;
     IPackageManager mIpm;
+    private final IDreamManager mDreamManager;
+    private final Context mContext;
     AssistUtils mAssistUtils;
     WindowManager mWm;
     IWindowManager mIwm;
@@ -135,6 +142,7 @@
     Display mDisplay;
     String mRecentsPackage;
     ComponentName mAssistComponent;
+    private int mCurrentUserId;
 
     boolean mIsSafeMode;
     boolean mHasFreeformWorkspaceSupport;
@@ -146,7 +154,8 @@
     Canvas mBgProtectionCanvas;
 
     private final Handler mHandler = new H();
-    private final ExecutorService mOnewayExecutor = Executors.newSingleThreadExecutor();
+
+    private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
 
     /**
      * An abstract class to track task stack changes.
@@ -160,7 +169,7 @@
         public void onTaskStackChangedBackground() { }
         public void onTaskStackChanged() { }
         public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) { }
-        public void onActivityPinned(String packageName) { }
+        public void onActivityPinned(String packageName, int taskId) { }
         public void onActivityUnpinned() { }
         public void onPinnedActivityRestartAttempt(boolean clearedTask) { }
         public void onPinnedStackAnimationStarted() { }
@@ -176,9 +185,9 @@
          * TaskStackListener should make this call to verify that we don't act on events from other
          * user's processes.
          */
-        protected final boolean checkCurrentUserId(boolean debug) {
+        protected final boolean checkCurrentUserId(Context context, boolean debug) {
             int processUserId = UserHandle.myUserId();
-            int currentUserId = KeyguardUpdateMonitor.getCurrentUser();
+            int currentUserId = SystemServicesProxy.getInstance(context).getCurrentUser();
             if (processUserId != currentUserId) {
                 if (debug) {
                     Log.d(TAG, "UID mismatch. SystemUI is running uid=" + processUserId
@@ -215,9 +224,9 @@
         }
 
         @Override
-        public void onActivityPinned(String packageName) throws RemoteException {
+        public void onActivityPinned(String packageName, int taskId) throws RemoteException {
             mHandler.removeMessages(H.ON_ACTIVITY_PINNED);
-            mHandler.obtainMessage(H.ON_ACTIVITY_PINNED, packageName).sendToTarget();
+            mHandler.obtainMessage(H.ON_ACTIVITY_PINNED, taskId, 0, packageName).sendToTarget();
         }
 
         @Override
@@ -275,6 +284,10 @@
         }
     };
 
+    private final UserInfoController.OnUserInfoChangedListener mOnUserInfoChangedListener =
+            (String name, Drawable picture, String userAccount) ->
+                    mCurrentUserId = mAm.getCurrentUser();
+
     /**
      * List of {@link TaskStackListener} registered from {@link #registerTaskStackListener}.
      */
@@ -282,6 +295,7 @@
 
     /** Private constructor */
     private SystemServicesProxy(Context context) {
+        mContext = context.getApplicationContext();
         mAccm = AccessibilityManager.getInstance(context);
         mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
         mIam = ActivityManager.getService();
@@ -293,6 +307,8 @@
         mIwm = WindowManagerGlobal.getWindowManagerService();
         mKgm = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
         mUm = UserManager.get(context);
+        mDreamManager = IDreamManager.Stub.asInterface(
+                ServiceManager.checkService(DreamService.DREAM_SERVICE));
         mDisplay = mWm.getDefaultDisplay();
         mRecentsPackage = context.getPackageName();
         mHasFreeformWorkspaceSupport =
@@ -300,6 +316,7 @@
                         Settings.Global.getInt(context.getContentResolver(),
                                 DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
         mIsSafeMode = mPm.isSafeMode();
+        mCurrentUserId = mAm.getCurrentUser();
 
         // Get the dummy thumbnail width/heights
         Resources res = context.getResources();
@@ -317,6 +334,12 @@
         // Resolve the assist intent
         mAssistComponent = mAssistUtils.getAssistComponentForUser(UserHandle.myUserId());
 
+        // Since SystemServicesProxy can be accessed from a per-SysUI process component, create a
+        // per-process listener to keep track of the current user id to reduce the number of binder
+        // calls to fetch it.
+        UserInfoController userInfoController = Dependency.get(UserInfoController.class);
+        userInfoController.addCallback(mOnUserInfoChangedListener);
+
         if (RecentsDebugFlags.Static.EnableMockTasks) {
             // Create a dummy icon
             mDummyIcon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
@@ -446,9 +469,18 @@
      * Returns the top running task.
      */
     public ActivityManager.RunningTaskInfo getRunningTask() {
-        List<ActivityManager.RunningTaskInfo> tasks = mAm.getRunningTasks(1);
+        // Note: The set of running tasks from the system is ordered by recency
+        List<ActivityManager.RunningTaskInfo> tasks = mAm.getRunningTasks(10);
         if (tasks != null && !tasks.isEmpty()) {
-            return tasks.get(0);
+            // Find the first task in a valid stack, we ignore everything from the Recents and PiP
+            // stacks
+            for (int i = 0; i < tasks.size(); i++) {
+                ActivityManager.RunningTaskInfo task = tasks.get(i);
+                int stackId = task.stackId;
+                if (stackId != RECENTS_STACK_ID && stackId != PINNED_STACK_ID) {
+                    return task;
+                }
+            }
         }
         return null;
     }
@@ -766,7 +798,7 @@
      * Sends a message to close other system windows.
      */
     public void sendCloseSystemWindows(String reason) {
-        mOnewayExecutor.submit(() -> {
+        mUiOffloadThread.submit(() -> {
             try {
                 mIam.closeSystemDialogs(reason);
             } catch (RemoteException e) {
@@ -1008,10 +1040,11 @@
     }
 
     /**
-     * Returns the current user id.
+     * Returns the current user id.  Used instead of KeyguardUpdateMonitor in SystemUI components
+     * that run in the non-primary SystemUI process.
      */
     public int getCurrentUser() {
-        return KeyguardUpdateMonitor.getCurrentUser();
+        return mCurrentUserId;
     }
 
     /**
@@ -1115,32 +1148,50 @@
         }
     }
 
+    public void startActivityAsUserAsync(Intent intent, ActivityOptions opts) {
+        mUiOffloadThread.submit(() -> mContext.startActivityAsUser(intent,
+                opts != null ? opts.toBundle() : null, UserHandle.CURRENT));
+    }
+
     /** Starts an activity from recents. */
-    public boolean startActivityFromRecents(Context context, Task.TaskKey taskKey, String taskName,
-            ActivityOptions options, int stackId) {
-        if (mIam != null) {
-            try {
-                if (taskKey.stackId == DOCKED_STACK_ID) {
-                    // We show non-visible docked tasks in Recents, but we always want to launch
-                    // them in the fullscreen stack.
-                    if (options == null) {
-                        options = ActivityOptions.makeBasic();
-                    }
-                    options.setLaunchStackId(FULLSCREEN_WORKSPACE_STACK_ID);
-                } else if (stackId != INVALID_STACK_ID){
-                    if (options == null) {
-                        options = ActivityOptions.makeBasic();
-                    }
-                    options.setLaunchStackId(stackId);
-                }
-                mIam.startActivityFromRecents(
-                        taskKey.id, options == null ? null : options.toBundle());
-                return true;
-            } catch (Exception e) {
-                Log.e(TAG, context.getString(R.string.recents_launch_error_message, taskName), e);
-            }
+    public void startActivityFromRecents(Context context, Task.TaskKey taskKey, String taskName,
+            ActivityOptions options, int stackId,
+            @Nullable final StartActivityFromRecentsResultListener resultListener) {
+        if (mIam == null) {
+            return;
         }
-        return false;
+        if (taskKey.stackId == DOCKED_STACK_ID) {
+            // We show non-visible docked tasks in Recents, but we always want to launch
+            // them in the fullscreen stack.
+            if (options == null) {
+                options = ActivityOptions.makeBasic();
+            }
+            options.setLaunchStackId(FULLSCREEN_WORKSPACE_STACK_ID);
+        } else if (stackId != INVALID_STACK_ID) {
+            if (options == null) {
+                options = ActivityOptions.makeBasic();
+            }
+            options.setLaunchStackId(stackId);
+        }
+        final ActivityOptions finalOptions = options;
+
+        // Execute this from another thread such that we can do other things (like caching the
+        // bitmap for the thumbnail) while AM is busy starting our activity.
+        mUiOffloadThread.submit(() -> {
+            try {
+                mIam.startActivityFromRecents(
+                        taskKey.id, finalOptions == null ? null : finalOptions.toBundle());
+                if (resultListener != null) {
+                    mHandler.post(() -> resultListener.onStartActivityResult(true));
+                }
+            } catch (Exception e) {
+                Log.e(TAG, context.getString(
+                        R.string.recents_launch_error_message, taskName), e);
+                if (resultListener != null) {
+                    mHandler.post(() -> resultListener.onStartActivityResult(false));
+                }
+            }
+        });
     }
 
     /** Starts an in-place animation on the front most application windows. */
@@ -1258,6 +1309,37 @@
         }
     }
 
+    public boolean isDreaming() {
+        try {
+            return mDreamManager.isDreaming();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to query dream manager.", e);
+        }
+        return false;
+    }
+
+    public void awakenDreamsAsync() {
+        mUiOffloadThread.submit(() -> {
+            try {
+                mDreamManager.awaken();
+            } catch (RemoteException e) {
+                e.printStackTrace();
+            }
+        });
+    }
+
+    public void updateOverviewLastStackActiveTimeAsync(long newLastStackActiveTime,
+            int currentUserId) {
+        mUiOffloadThread.submit(() -> {
+            Settings.Secure.putLongForUser(mContext.getContentResolver(),
+                    Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME, newLastStackActiveTime, currentUserId);
+        });
+    }
+
+    public interface StartActivityFromRecentsResultListener {
+        void onStartActivityResult(boolean succeeded);
+    }
+
     private final class H extends Handler {
         private static final int ON_TASK_STACK_CHANGED = 1;
         private static final int ON_TASK_SNAPSHOT_CHANGED = 2;
@@ -1294,7 +1376,7 @@
                     }
                     case ON_ACTIVITY_PINNED: {
                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                            mTaskStackListeners.get(i).onActivityPinned((String) msg.obj);
+                            mTaskStackListeners.get(i).onActivityPinned((String) msg.obj, msg.arg1);
                         }
                         break;
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index 7ee0906..93033ea 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -22,7 +22,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
-import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -33,15 +32,13 @@
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
 
-import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.RecentsDebugFlags;
 import com.android.systemui.recents.misc.SystemServicesProxy;
-
 import com.android.systemui.recents.views.grid.TaskGridLayoutAlgorithm;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -87,7 +84,7 @@
         mCurrentQuietProfiles.clear();
 
         if (currentUserId == UserHandle.USER_CURRENT) {
-            currentUserId = KeyguardUpdateMonitor.getCurrentUser();
+            currentUserId = SystemServicesProxy.getInstance(mContext).getCurrentUser();
         }
         UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         List<UserInfo> profiles = userManager.getProfiles(currentUserId);
@@ -218,8 +215,8 @@
             affiliatedTasks.put(taskKey.id, taskKey);
         }
         if (newLastStackActiveTime != -1) {
-            Settings.Secure.putLongForUser(mContext.getContentResolver(),
-                    Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME, newLastStackActiveTime, currentUserId);
+            Recents.getSystemServices().updateOverviewLastStackActiveTimeAsync(
+                    newLastStackActiveTime, currentUserId);
         }
 
         // Initialize the stacks
@@ -316,9 +313,8 @@
             for (int i = 0; i < users.size(); i++) {
                 int userId = users.get(i).id;
                 if (userId != currentUserId) {
-                    Settings.Secure.putLongForUser(mContext.getContentResolver(),
-                            Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME, legacyLastStackActiveTime,
-                            userId);
+                    Recents.getSystemServices().updateOverviewLastStackActiveTimeAsync(
+                            legacyLastStackActiveTime, userId);
                 }
             }
             return legacyLastStackActiveTime;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index 97a9659..15e1739 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -28,6 +28,7 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
+import android.os.Trace;
 import android.util.Log;
 import android.util.LruCache;
 
@@ -102,6 +103,7 @@
     Bitmap mDefaultThumbnail;
     BitmapDrawable mDefaultIcon;
 
+    boolean mStarted;
     boolean mCancelled;
     boolean mWaitingOnLoadQueue;
 
@@ -121,16 +123,21 @@
                 android.os.Process.THREAD_PRIORITY_BACKGROUND);
         mLoadThread.start();
         mLoadThreadHandler = new Handler(mLoadThread.getLooper());
-        mLoadThreadHandler.post(this);
     }
 
     /** Restarts the loader thread */
     void start(Context context) {
         mContext = context;
         mCancelled = false;
-        // Notify the load thread to start loading
-        synchronized(mLoadThread) {
-            mLoadThread.notifyAll();
+        if (!mStarted) {
+            // Start loading on the load thread
+            mStarted = true;
+            mLoadThreadHandler.post(this);
+        } else {
+            // Notify the load thread to start loading again
+            synchronized (mLoadThread) {
+                mLoadThread.notifyAll();
+            }
         }
     }
 
@@ -351,7 +358,12 @@
     /** Preloads recents tasks using the specified plan to store the output. */
     public synchronized void preloadTasks(RecentsTaskLoadPlan plan, int runningTaskId,
             boolean includeFrontMostExcludedTask) {
-        plan.preloadPlan(this, runningTaskId, includeFrontMostExcludedTask);
+        try {
+            Trace.beginSection("preloadPlan");
+            plan.preloadPlan(this, runningTaskId, includeFrontMostExcludedTask);
+        } finally {
+            Trace.endSection();
+        }
     }
 
     /** Begins loading the heavy task data according to the specified options. */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index 9b25ef8..6e3be09 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -229,7 +229,8 @@
          * Notifies when a task has been removed from the stack.
          */
         void onStackTaskRemoved(TaskStack stack, Task removedTask, Task newFrontMostTask,
-                AnimationProps animation, boolean fromDockGesture);
+                AnimationProps animation, boolean fromDockGesture,
+                boolean dismissRecentsIfAllRemoved);
 
         /**
          * Notifies when all tasks have been removed from the stack.
@@ -631,13 +632,22 @@
      * how they should update themselves.
      */
     public void removeTask(Task t, AnimationProps animation, boolean fromDockGesture) {
+        removeTask(t, animation, fromDockGesture, true /* dismissRecentsIfAllRemoved */);
+    }
+
+    /**
+     * Removes a task from the stack, with an additional {@param animation} hint to the callbacks on
+     * how they should update themselves.
+     */
+    public void removeTask(Task t, AnimationProps animation, boolean fromDockGesture,
+            boolean dismissRecentsIfAllRemoved) {
         if (mStackTaskList.contains(t)) {
             removeTaskImpl(mStackTaskList, t);
             Task newFrontMostTask = getStackFrontMostTask(false  /* includeFreeform */);
             if (mCb != null) {
                 // Notify that a task has been removed
                 mCb.onStackTaskRemoved(this, t, newFrontMostTask, animation,
-                        fromDockGesture);
+                        fromDockGesture, dismissRecentsIfAllRemoved);
             }
         }
         mRawTaskList.remove(t);
@@ -646,19 +656,27 @@
     /**
      * Removes all tasks from the stack.
      */
-    public void removeAllTasks() {
+    public void removeAllTasks(boolean notifyStackChanges) {
         ArrayList<Task> tasks = mStackTaskList.getTasks();
         for (int i = tasks.size() - 1; i >= 0; i--) {
             Task t = tasks.get(i);
             removeTaskImpl(mStackTaskList, t);
             mRawTaskList.remove(t);
         }
-        if (mCb != null) {
+        if (mCb != null && notifyStackChanges) {
             // Notify that all tasks have been removed
             mCb.onStackTasksRemoved(this);
         }
     }
 
+
+    /**
+     * @see #setTasks(Context, List, boolean, boolean)
+     */
+    public void setTasks(Context context, TaskStack stack, boolean notifyStackChanges) {
+        setTasks(context, stack.mRawTaskList, notifyStackChanges);
+    }
+
     /**
      * Sets a few tasks in one go, without calling any callbacks.
      *
@@ -723,7 +741,8 @@
         Task newFrontMostTask = getStackFrontMostTask(false);
         for (int i = 0; i < removedTaskCount; i++) {
             mCb.onStackTaskRemoved(this, removedTasks.get(i), newFrontMostTask,
-                    AnimationProps.IMMEDIATE, false /* fromDockGesture */);
+                    AnimationProps.IMMEDIATE, false /* fromDockGesture */,
+                    true /* dismissRecentsIfAllRemoved */);
         }
 
         // Only callback for the newly added tasks after this stack has been updated
@@ -854,21 +873,46 @@
     }
 
     /**
+     * Returns whether the next launch target should actually be the PiP task.
+     */
+    public boolean isNextLaunchTargetPip(long lastPipTime) {
+        Task launchTarget = getLaunchTarget();
+        Task nextLaunchTarget = getNextLaunchTargetRaw();
+        if (nextLaunchTarget != null && lastPipTime > 0) {
+            // If the PiP time is more recent than the next launch target, then launch the PiP task
+            return lastPipTime > nextLaunchTarget.key.lastActiveTime;
+        } else if (launchTarget != null && lastPipTime > 0 && getTaskCount() == 1) {
+            // Otherwise, if there is no next launch target, but there is a PiP, then launch
+            // the PiP task
+            return true;
+        }
+        return false;
+    }
+
+    /**
      * Returns the task in stack tasks which should be launched next if Recents are toggled
-     * again, or null if there is no task to be launched.
+     * again, or null if there is no task to be launched. Callers should check
+     * {@link #isNextLaunchTargetPip(long)} before fetching the next raw launch target from the
+     * stack.
      */
     public Task getNextLaunchTarget() {
+        Task nextLaunchTarget = getNextLaunchTargetRaw();
+        if (nextLaunchTarget != null) {
+            return nextLaunchTarget;
+        }
+        return getStackTasks().get(getTaskCount() - 1);
+    }
+
+    private Task getNextLaunchTargetRaw() {
         int taskCount = getTaskCount();
         if (taskCount == 0) {
             return null;
         }
         int launchTaskIndex = indexOfStackTask(getLaunchTarget());
-        if (launchTaskIndex != -1) {
-            launchTaskIndex = Math.max(0, launchTaskIndex - 1);
-        } else {
-            launchTaskIndex = getTaskCount() - 1;
+        if (launchTaskIndex != -1 && launchTaskIndex > 0) {
+            return getStackTasks().get(launchTaskIndex - 1);
         }
-        return getStackTasks().get(launchTaskIndex);
+        return null;
     }
 
     /** Returns the index of this task in this current task stack */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index 8882cab..d7d264e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -101,57 +101,49 @@
      */
     public void launchTaskFromRecents(final TaskStack stack, @Nullable final Task task,
             final TaskStackView stackView, final TaskView taskView,
-            final boolean screenPinningRequested, final Rect bounds, final int destinationStack) {
-        final ActivityOptions opts = ActivityOptions.makeBasic();
-        if (bounds != null) {
-            opts.setLaunchBounds(bounds.isEmpty() ? null : bounds);
-        }
+            final boolean screenPinningRequested, final int destinationStack) {
 
         final ActivityOptions.OnAnimationStartedListener animStartedListener;
-        final IAppTransitionAnimationSpecsFuture transitionFuture;
+        final AppTransitionAnimationSpecsFuture transitionFuture;
         if (taskView != null) {
-            transitionFuture = getAppTransitionFuture(new AnimationSpecComposer() {
-                @Override
-                public List<AppTransitionAnimationSpec> composeSpecs() {
-                    return composeAnimationSpecs(task, stackView, destinationStack);
-                }
-            });
-            animStartedListener = new ActivityOptions.OnAnimationStartedListener() {
-                @Override
-                public void onAnimationStarted() {
-                    // If we are launching into another task, cancel the previous task's
-                    // window transition
-                    EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
-                    EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
-                    stackView.cancelAllTaskViewAnimations();
 
-                    if (screenPinningRequested) {
-                        // Request screen pinning after the animation runs
-                        mStartScreenPinningRunnable.taskId = task.key.id;
-                        mHandler.postDelayed(mStartScreenPinningRunnable, 350);
-                    }
+            // Fetch window rect here already in order not to be blocked on lock contention in WM
+            // when the future calls it.
+            final Rect windowRect = Recents.getSystemServices().getWindowRect();
+            transitionFuture = getAppTransitionFuture(
+                    () -> composeAnimationSpecs(task, stackView, destinationStack, windowRect));
+            animStartedListener = () -> {
+                // If we are launching into another task, cancel the previous task's
+                // window transition
+                EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
+                EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
+                stackView.cancelAllTaskViewAnimations();
+
+                if (screenPinningRequested) {
+                    // Request screen pinning after the animation runs
+                    mStartScreenPinningRunnable.taskId = task.key.id;
+                    mHandler.postDelayed(mStartScreenPinningRunnable, 350);
                 }
             };
         } else {
             // This is only the case if the task is not on screen (scrolled offscreen for example)
             transitionFuture = null;
-            animStartedListener = new ActivityOptions.OnAnimationStartedListener() {
-                @Override
-                public void onAnimationStarted() {
-                    // If we are launching into another task, cancel the previous task's
-                    // window transition
-                    EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
-                    EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
-                    stackView.cancelAllTaskViewAnimations();
-                }
+            animStartedListener = () -> {
+                // If we are launching into another task, cancel the previous task's
+                // window transition
+                EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
+                EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
+                stackView.cancelAllTaskViewAnimations();
             };
         }
 
+        final ActivityOptions opts = ActivityOptions.makeMultiThumbFutureAspectScaleAnimation(mContext,
+                mHandler, transitionFuture != null ? transitionFuture.future : null,
+                animStartedListener, true /* scaleUp */);
         if (taskView == null) {
             // If there is no task view, then we do not need to worry about animating out occluding
             // task views, and we can launch immediately
-            startTaskActivity(stack, task, taskView, opts, transitionFuture, animStartedListener,
-                    destinationStack);
+            startTaskActivity(stack, task, taskView, opts, transitionFuture, destinationStack);
         } else {
             LaunchTaskStartedEvent launchStartedEvent = new LaunchTaskStartedEvent(taskView,
                     screenPinningRequested);
@@ -160,14 +152,13 @@
                     @Override
                     public void run() {
                         startTaskActivity(stack, task, taskView, opts, transitionFuture,
-                                animStartedListener, destinationStack);
+                                destinationStack);
                     }
                 });
                 EventBus.getDefault().send(launchStartedEvent);
             } else {
                 EventBus.getDefault().send(launchStartedEvent);
-                startTaskActivity(stack, task, taskView, opts, transitionFuture,
-                        animStartedListener, destinationStack);
+                startTaskActivity(stack, task, taskView, opts, transitionFuture, destinationStack);
             }
         }
         Recents.getSystemServices().sendCloseSystemWindows(
@@ -199,30 +190,31 @@
      * @param destinationStack id of the stack to put the task into.
      */
     private void startTaskActivity(TaskStack stack, Task task, @Nullable TaskView taskView,
-            ActivityOptions opts, IAppTransitionAnimationSpecsFuture transitionFuture,
-            final OnAnimationStartedListener animStartedListener, int destinationStack) {
+            ActivityOptions opts, AppTransitionAnimationSpecsFuture transitionFuture,
+            int destinationStack) {
         SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.startActivityFromRecents(mContext, task.key, task.title, opts, destinationStack)) {
-            // Keep track of the index of the task launch
-            int taskIndexFromFront = 0;
-            int taskIndex = stack.indexOfStackTask(task);
-            if (taskIndex > -1) {
-                taskIndexFromFront = stack.getTaskCount() - taskIndex - 1;
-            }
-            EventBus.getDefault().send(new LaunchTaskSucceededEvent(taskIndexFromFront));
-        } else {
-            // Dismiss the task if we fail to launch it
-            if (taskView != null) {
-                taskView.dismissTask();
-            }
+        ssp.startActivityFromRecents(mContext, task.key, task.title, opts, destinationStack,
+                succeeded -> {
+            if (succeeded) {
+                // Keep track of the index of the task launch
+                int taskIndexFromFront = 0;
+                int taskIndex = stack.indexOfStackTask(task);
+                if (taskIndex > -1) {
+                    taskIndexFromFront = stack.getTaskCount() - taskIndex - 1;
+                }
+                EventBus.getDefault().send(new LaunchTaskSucceededEvent(taskIndexFromFront));
+            } else {
+                // Dismiss the task if we fail to launch it
+                if (taskView != null) {
+                    taskView.dismissTask();
+                }
 
-            // Keep track of failed launches
-            EventBus.getDefault().send(new LaunchTaskFailedEvent());
-        }
-
+                // Keep track of failed launches
+                EventBus.getDefault().send(new LaunchTaskFailedEvent());
+            }
+        });
         if (transitionFuture != null) {
-            ssp.overridePendingAppTransitionMultiThumbFuture(transitionFuture,
-                    wrapStartedListener(animStartedListener), true /* scaleUp */);
+            mHandler.post(transitionFuture::precacheSpecs);
         }
     }
 
@@ -231,21 +223,18 @@
      *
      * @param composer The implementation that composes the specs on the UI thread.
      */
-    public IAppTransitionAnimationSpecsFuture getAppTransitionFuture(
+    public AppTransitionAnimationSpecsFuture getAppTransitionFuture(
             final AnimationSpecComposer composer) {
         synchronized (this) {
             mAppTransitionAnimationSpecs = SPECS_WAITING;
         }
-        return new IAppTransitionAnimationSpecsFuture.Stub() {
+        IAppTransitionAnimationSpecsFuture future = new IAppTransitionAnimationSpecsFuture.Stub() {
             @Override
             public AppTransitionAnimationSpec[] get() throws RemoteException {
-                mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        synchronized (RecentsTransitionHelper.this) {
-                            mAppTransitionAnimationSpecs = composer.composeSpecs();
-                            RecentsTransitionHelper.this.notifyAll();
-                        }
+                mHandler.post(() -> {
+                    synchronized (RecentsTransitionHelper.this) {
+                        mAppTransitionAnimationSpecs = composer.composeSpecs();
+                        RecentsTransitionHelper.this.notifyAll();
                     }
                 });
                 synchronized (RecentsTransitionHelper.this) {
@@ -265,6 +254,7 @@
                 }
             }
         };
+        return new AppTransitionAnimationSpecsFuture(composer, future);
     }
 
     /**
@@ -283,7 +273,7 @@
      * Composes the animation specs for all the tasks in the target stack.
      */
     private List<AppTransitionAnimationSpec> composeAnimationSpecs(final Task task,
-            final TaskStackView stackView, final int destinationStack) {
+            final TaskStackView stackView, final int destinationStack, Rect windowRect) {
         // Ensure we have a valid target stack id
         final int targetStackId = destinationStack != INVALID_STACK_ID ?
                 destinationStack : task.key.stackId;
@@ -309,8 +299,7 @@
                 specs.add(composeOffscreenAnimationSpec(task, offscreenTaskRect));
             } else {
                 mTmpTransform.fillIn(taskView);
-                stackLayout.transformToScreenCoordinates(mTmpTransform,
-                        null /* windowOverrideRect */);
+                stackLayout.transformToScreenCoordinates(mTmpTransform, windowRect);
                 AppTransitionAnimationSpec spec = composeAnimationSpec(stackView, taskView,
                         mTmpTransform, true /* addHeaderBitmap */);
                 if (spec != null) {
@@ -430,4 +419,34 @@
     public interface AnimationSpecComposer {
         List<AppTransitionAnimationSpec> composeSpecs();
     }
+
+    /**
+     * Class to be returned from {@link #composeAnimationSpec} that gives access to both the future
+     * and the anonymous class used for composing.
+     */
+    public class AppTransitionAnimationSpecsFuture {
+
+        private final AnimationSpecComposer composer;
+        private final IAppTransitionAnimationSpecsFuture future;
+
+        private AppTransitionAnimationSpecsFuture(AnimationSpecComposer composer,
+                IAppTransitionAnimationSpecsFuture future) {
+            this.composer = composer;
+            this.future = future;
+        }
+
+        public IAppTransitionAnimationSpecsFuture getFuture() {
+            return future;
+        }
+
+        /**
+         * Manually generates and caches the spec such that they are already available when the
+         * future needs.
+         */
+        public void precacheSpecs() {
+            synchronized (RecentsTransitionHelper.this) {
+                mAppTransitionAnimationSpecs = composer.composeSpecs();
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 6879436..978533c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -25,19 +25,16 @@
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.Outline;
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.view.AppTransitionAnimationSpec;
-import android.view.IAppTransitionAnimationSpecsFuture;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewDebug;
-import android.view.ViewOutlineProvider;
 import android.view.ViewPropertyAnimator;
 import android.view.WindowInsets;
 import android.widget.FrameLayout;
@@ -60,7 +57,9 @@
 import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
 import com.android.systemui.recents.events.activity.LaunchTaskEvent;
 import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
+import com.android.systemui.recents.events.activity.ShowEmptyViewEvent;
 import com.android.systemui.recents.events.activity.ShowStackActionButtonEvent;
+import com.android.systemui.recents.events.component.ExpandPipEvent;
 import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
 import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
 import com.android.systemui.recents.events.ui.DraggingInRecentsEndedEvent;
@@ -75,13 +74,13 @@
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
 import com.android.systemui.recents.views.RecentsTransitionHelper.AnimationSpecComposer;
+import com.android.systemui.recents.views.RecentsTransitionHelper.AppTransitionAnimationSpecsFuture;
 import com.android.systemui.stackdivider.WindowManagerProxy;
 import com.android.systemui.statusbar.FlingAnimationUtils;
 
 import com.google.android.colorextraction.ColorExtractor;
 import com.google.android.colorextraction.drawable.GradientDrawable;
 
-import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
@@ -259,6 +258,12 @@
 
     /** Launches the task that recents was launched from if possible */
     public boolean launchPreviousTask() {
+        if (Recents.getConfiguration().getLaunchState().launchedFromPipApp) {
+            // If the app auto-entered PiP on the way to Recents, then just re-expand it
+            EventBus.getDefault().send(new ExpandPipEvent());
+            return true;
+        }
+
         if (mTaskStackView != null) {
             Task task = getStack().getLaunchTarget();
             if (task != null) {
@@ -451,8 +456,7 @@
     public final void onBusEvent(LaunchTaskEvent event) {
         mLastTaskLaunchedWasFreeform = event.task.isFreeformTask();
         mTransitionHelper.launchTaskFromRecents(getStack(), event.task, mTaskStackView,
-                event.taskView, event.screenPinningRequested, event.targetTaskBounds,
-                event.targetTaskStack);
+                event.taskView, event.screenPinningRequested, event.targetTaskStack);
     }
 
     public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {
@@ -534,7 +538,7 @@
                 };
 
                 final Rect taskRect = getTaskRect(event.taskView);
-                IAppTransitionAnimationSpecsFuture future =
+                AppTransitionAnimationSpecsFuture future =
                         mTransitionHelper.getAppTransitionFuture(
                                 new AnimationSpecComposer() {
                                     @Override
@@ -543,7 +547,7 @@
                                                 event.taskView, taskRect);
                                     }
                                 });
-                ssp.overridePendingAppTransitionMultiThumbFuture(future,
+                ssp.overridePendingAppTransitionMultiThumbFuture(future.getFuture(),
                         mTransitionHelper.wrapStartedListener(startedListener),
                         true /* scaleUp */);
 
@@ -650,6 +654,10 @@
         updateStack(event.stack, false /* setStackViewTasks */);
     }
 
+    public final void onBusEvent(ShowEmptyViewEvent event) {
+        showEmptyView(R.string.recents_empty_message);
+    }
+
     /**
      * Shows the stack action button.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index 7ba705e..8135034 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -562,7 +562,8 @@
             mMinScrollP = 0;
             mMaxScrollP = Math.max(mMinScrollP, (mNumStackTasks - 1) -
                     Math.max(0, mFocusedRange.getAbsoluteX(maxBottomNormX)));
-            if (launchState.launchedFromHome) {
+            if (launchState.launchedFromHome || launchState.launchedFromPipApp
+                    || launchState.launchedWithNextPipApp) {
                 mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
             } else {
                 mInitialScrollP = Utilities.clamp(launchTaskIndex - 1, mMinScrollP, mMaxScrollP);
@@ -581,8 +582,8 @@
             mMinScrollP = 0;
             mMaxScrollP = Math.max(mMinScrollP, (mNumStackTasks - 1) -
                     Math.max(0, mUnfocusedRange.getAbsoluteX(maxBottomNormX)));
-            boolean scrollToFront = launchState.launchedFromHome ||
-                    launchState.launchedViaDockGesture;
+            boolean scrollToFront = launchState.launchedFromHome || launchState.launchedFromPipApp
+                    || launchState.launchedWithNextPipApp || launchState.launchedViaDockGesture;
             if (launchState.launchedFromBlacklistedApp) {
                 mInitialScrollP = mMaxScrollP;
             } else if (launchState.launchedWithAltTab) {
@@ -608,6 +609,8 @@
         mTaskIndexOverrideMap.clear();
 
         boolean scrollToFront = launchState.launchedFromHome ||
+                launchState.launchedFromPipApp ||
+                launchState.launchedWithNextPipApp ||
                 launchState.launchedFromBlacklistedApp ||
                 launchState.launchedViaDockGesture;
         if (getInitialFocusState() == STATE_UNFOCUSED && mNumStackTasks > 1) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 18a9bab..5f9a8f5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -57,6 +57,7 @@
 import com.android.systemui.recents.RecentsActivityLaunchState;
 import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.RecentsDebugFlags;
+import com.android.systemui.recents.RecentsImpl;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
 import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
@@ -72,7 +73,11 @@
 import com.android.systemui.recents.events.activity.LaunchTaskStartedEvent;
 import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
 import com.android.systemui.recents.events.activity.PackagesChangedEvent;
+import com.android.systemui.recents.events.activity.ShowEmptyViewEvent;
 import com.android.systemui.recents.events.activity.ShowStackActionButtonEvent;
+import com.android.systemui.recents.events.component.ActivityPinnedEvent;
+import com.android.systemui.recents.events.component.ExpandPipEvent;
+import com.android.systemui.recents.events.component.HidePipMenuEvent;
 import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
 import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
 import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
@@ -379,8 +384,7 @@
 
         // Only notify if we are already initialized, otherwise, everything will pick up all the
         // new and old tasks when we next layout
-        mStack.setTasks(getContext(), stack.computeAllTasksList(),
-                allowNotifyStackChanges && isInitialized);
+        mStack.setTasks(getContext(), stack, allowNotifyStackChanges && isInitialized);
     }
 
     /** Returns the task stack. */
@@ -1496,7 +1500,7 @@
      */
     @Override
     public void onStackTaskRemoved(TaskStack stack, Task removedTask, Task newFrontMostTask,
-            AnimationProps animation, boolean fromDockGesture) {
+            AnimationProps animation, boolean fromDockGesture, boolean dismissRecentsIfAllRemoved) {
         if (mFocusedTask == removedTask) {
             resetFocusedTask(removedTask);
         }
@@ -1527,9 +1531,13 @@
 
         // If there are no remaining tasks, then just close recents
         if (mStack.getTaskCount() == 0) {
-            EventBus.getDefault().send(new AllTaskViewsDismissedEvent(fromDockGesture
-                    ? R.string.recents_empty_message
-                    : R.string.recents_empty_message_dismissed_all));
+            if (dismissRecentsIfAllRemoved) {
+                EventBus.getDefault().send(new AllTaskViewsDismissedEvent(fromDockGesture
+                        ? R.string.recents_empty_message
+                        : R.string.recents_empty_message_dismissed_all));
+            } else {
+                EventBus.getDefault().send(new ShowEmptyViewEvent());
+            }
         }
     }
 
@@ -1802,14 +1810,36 @@
             return;
         }
 
-        final Task launchTask = mStack.getNextLaunchTarget();
-        if (launchTask != null) {
-            launchTask(launchTask);
-            MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK,
-                    launchTask.key.getComponent().toString());
-        } else if (mStack.getTaskCount() == 0) {
-            // If there are no tasks, then just hide recents back to home.
-            EventBus.getDefault().send(new HideRecentsEvent(false, true));
+        if (mStack.getTaskCount() == 0) {
+            if (RecentsImpl.getLastPipTime() != -1) {
+                EventBus.getDefault().send(new ExpandPipEvent());
+                MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK,
+                        "pip");
+            } else {
+                // If there are no tasks, then just hide recents back to home.
+                EventBus.getDefault().send(new HideRecentsEvent(false, true));
+            }
+            return;
+        }
+
+        if (!Recents.getConfiguration().getLaunchState().launchedFromPipApp
+                && mStack.isNextLaunchTargetPip(RecentsImpl.getLastPipTime())) {
+            // If the launch task is in the pinned stack, then expand the PiP now
+            EventBus.getDefault().send(new ExpandPipEvent());
+            MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK, "pip");
+        } else {
+            final Task launchTask = mStack.getNextLaunchTarget();
+            if (launchTask != null) {
+                // Defer launching the task until the PiP menu has been dismissed (if it is
+                // showing at all)
+                HidePipMenuEvent hideMenuEvent = new HidePipMenuEvent();
+                hideMenuEvent.addPostAnimationCallback(() -> {
+                    launchTask(launchTask);
+                });
+                EventBus.getDefault().send(hideMenuEvent);
+                MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK,
+                        launchTask.key.getComponent().toString());
+            }
         }
     }
 
@@ -1871,7 +1901,7 @@
                         R.string.accessibility_recents_all_items_dismissed));
 
                 // Remove all tasks and delete the task data for all tasks
-                mStack.removeAllTasks();
+                mStack.removeAllTasks(true /* notifyStackChanges */);
                 for (int i = tasks.size() - 1; i >= 0; i--) {
                     EventBus.getDefault().send(new DeleteTaskDataEvent(tasks.get(i)));
                 }
@@ -2217,11 +2247,23 @@
         }
     }
 
+    public final void onBusEvent(ActivityPinnedEvent event) {
+        // If an activity enters PiP while Recents is open, remove the stack task associated with
+        // the new PiP task
+        Task removeTask = mStack.findTaskWithId(event.taskId);
+        if (removeTask != null) {
+            // In this case, we remove the task, but if the last task is removed, don't dismiss
+            // Recents to home
+            mStack.removeTask(removeTask, AnimationProps.IMMEDIATE, false /* fromDockGesture */,
+                    false /* dismissRecentsIfAllRemoved */);
+        }
+        updateLayoutAlgorithm(false /* boundScroll */);
+        updateToInitialState();
+    }
+
     public void reloadOnConfigurationChange() {
         mStableLayoutAlgorithm.reloadOnConfigurationChange(getContext());
         mLayoutAlgorithm.reloadOnConfigurationChange(getContext());
-
-        boolean hasDockedTask = Recents.getSystemServices().hasDockedTask();
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 24a2927..0c77036 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -1169,7 +1169,7 @@
     }
 
     public final void onBusEvent(RecentsActivityStartingEvent recentsActivityStartingEvent) {
-        if (mGrowRecents && getWindowManagerProxy().getDockSide() == WindowManager.DOCKED_TOP
+        if (mGrowRecents && mDockSide == WindowManager.DOCKED_TOP
                 && getSnapAlgorithm().getMiddleTarget() != getSnapAlgorithm().getLastSplitTarget()
                 && getCurrentPosition() == getSnapAlgorithm().getLastSplitTarget().position) {
             mState.growAfterRecentsDrawn = true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index be221bb..bf89b01 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -279,7 +279,9 @@
     public void toggleRecentApps() {
         synchronized (mLock) {
             mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS);
-            mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null).sendToTarget();
+            Message msg = mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS, 0, 0, null);
+            msg.setAsynchronous(true);
+            msg.sendToTarget();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index de2bdde..49c3f7e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar;
 
-import android.app.ActivityManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -207,7 +206,16 @@
      *
      * @return {@code null} or an empty string if a trust indication text should not be shown.
      */
-    protected String getTrustIndication() {
+    protected String getTrustGrantedIndication() {
+        return null;
+    }
+
+    /**
+     * Returns the indication text indicating that trust is currently being managed.
+     *
+     * @return {@code null} or an empty string if a trust managed text should not be shown.
+     */
+    protected String getTrustManagedIndication() {
         return null;
     }
 
@@ -280,17 +288,18 @@
             }
 
             KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
-            int userId = ActivityManager.getCurrentUser();
-            String trustIndication = getTrustIndication();
+            int userId = KeyguardUpdateMonitor.getCurrentUser();
+            String trustGrantedIndication = getTrustGrantedIndication();
+            String trustManagedIndication = getTrustManagedIndication();
             if (!mUserManager.isUserUnlocked(userId)) {
                 mTextView.switchIndication(com.android.internal.R.string.lockscreen_storage_locked);
                 mTextView.setTextColor(Color.WHITE);
             } else if (!TextUtils.isEmpty(mTransientIndication)) {
                 mTextView.switchIndication(mTransientIndication);
                 mTextView.setTextColor(mTransientTextColor);
-            } else if (!TextUtils.isEmpty(trustIndication)
+            } else if (!TextUtils.isEmpty(trustGrantedIndication)
                     && updateMonitor.getUserHasTrust(userId)) {
-                mTextView.switchIndication(trustIndication);
+                mTextView.switchIndication(trustGrantedIndication);
                 mTextView.setTextColor(Color.WHITE);
             } else if (mPowerPluggedIn) {
                 String indication = computePowerIndication();
@@ -299,7 +308,11 @@
                 }
                 mTextView.switchIndication(indication);
                 mTextView.setTextColor(Color.WHITE);
-
+            } else if (!TextUtils.isEmpty(trustManagedIndication)
+                    && updateMonitor.getUserTrustIsManaged(userId)
+                    && !updateMonitor.getUserHasTrust(userId)) {
+                mTextView.switchIndication(trustManagedIndication);
+                mTextView.setTextColor(Color.WHITE);
             } else {
                 mTextView.switchIndication(mRestingIndication);
                 mTextView.setTextColor(Color.WHITE);
@@ -379,6 +392,9 @@
     };
 
     public void setDozing(boolean dozing) {
+        if (mDozing == dozing) {
+            return;
+        }
         mDozing = dozing;
         updateIndication();
         updateDisclosure();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
index 8588668..a6c0cd1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
@@ -140,6 +140,9 @@
         mDrawable = drawable;
         mDrawable.setCallback(this);
         mDrawable.setBounds(getLeft(), getTop(), getRight(), getBottom());
+        mDrawable.setAlpha((int) (255 * mViewAlpha));
+        setDrawAsSrc(mDrawAsSrc);
+        updateScreenSize();
         invalidate();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 7162b31..f1d3e8c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -23,9 +23,11 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
@@ -33,6 +35,7 @@
 import android.view.ViewStub;
 import android.view.WindowManager;
 import android.widget.LinearLayout;
+
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
@@ -41,6 +44,7 @@
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
+import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
 import com.android.systemui.statusbar.phone.NavigationBarView;
@@ -62,6 +66,7 @@
 
     private CarBatteryController mCarBatteryController;
     private BatteryMeterView mBatteryMeterView;
+    private Drawable mNotificationPanelBackground;
 
     private ConnectedDeviceSignalController mConnectedDeviceSignalController;
     private CarNavigationBarView mNavigationBarView;
@@ -91,17 +96,18 @@
     protected void makeStatusBarView() {
         super.makeStatusBarView();
 
+        mNotificationPanelBackground = getDefaultWallpaper();
+        mScrimController.setScrimBehindDrawable(mNotificationPanelBackground);
+
         FragmentHostManager manager = FragmentHostManager.get(mStatusBarWindow);
         manager.addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
-            mBatteryMeterView = ((BatteryMeterView) fragment.getView().findViewById(
-                    R.id.battery));
+            mBatteryMeterView = fragment.getView().findViewById(R.id.battery);
 
             // By default, the BatteryMeterView should not be visible. It will be toggled
             // when a device has connected by bluetooth.
             mBatteryMeterView.setVisibility(View.GONE);
 
-            ViewStub stub = (ViewStub) fragment.getView().findViewById(
-                    R.id.connected_device_signals_stub);
+            ViewStub stub = fragment.getView().findViewById(R.id.connected_device_signals_stub);
             View signalsView = stub.inflate();
 
             // When a ViewStub if inflated, it does not respect the margins on the
@@ -256,7 +262,7 @@
         if (userSwitcherController.useFullscreenUserSwitcher()) {
             mFullscreenUserSwitcher = new FullscreenUserSwitcher(this,
                     userSwitcherController,
-                    (ViewStub) mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub));
+                    mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub));
         } else {
             super.createUserSwitcher();
         }
@@ -314,6 +320,27 @@
         return startActivityWithOptions(intent, options.toBundle());
     }
 
+    @Override
+    protected boolean shouldPeek(NotificationData.Entry entry, StatusBarNotification sbn) {
+        // Because space is usually constrained in the auto use-case, there should not be a
+        // pinned notification when the shade has been expanded. Ensure this by not pinning any
+        // notification if the shade is already opened.
+        if (mPanelExpanded) {
+            return false;
+        }
+
+        return super.shouldPeek(entry, sbn);
+    }
+
+    @Override
+    public void animateExpandNotificationsPanel() {
+        // Because space is usually constrained in the auto use-case, there should not be a
+        // pinned notification when the shade has been expanded. Ensure this by removing all heads-
+        // up notifications.
+        mHeadsUpManager.removeAllHeadsUpEntries();
+        super.animateExpandNotificationsPanel();
+    }
+
     /**
      * Ensures that relevant child views are appropriately recreated when the device's density
      * changes.
@@ -322,5 +349,17 @@
     protected void onDensityOrFontScaleChanged() {
         super.onDensityOrFontScaleChanged();
         mController.onDensityOrFontScaleChanged();
+
+        // Need to update the background on density changed in case the change was due to night
+        // mode.
+        mNotificationPanelBackground = getDefaultWallpaper();
+        mScrimController.setScrimBehindDrawable(mNotificationPanelBackground);
+    }
+
+    /**
+     * Returns the {@link Drawable} that represents the wallpaper that the user has currently set.
+     */
+    private Drawable getDefaultWallpaper() {
+        return mContext.getDrawable(com.android.internal.R.drawable.default_wallpaper);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MediaNotificationProcessor.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MediaNotificationProcessor.java
index 9a3de61..80854ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MediaNotificationProcessor.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MediaNotificationProcessor.java
@@ -24,7 +24,6 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.support.annotation.VisibleForTesting;
-import android.support.v4.graphics.ColorUtils;
 import android.support.v7.graphics.Palette;
 import android.util.LayoutDirection;
 
@@ -41,10 +40,31 @@
     /**
      * The fraction below which we select the vibrant instead of the light/dark vibrant color
      */
-    private static final float POPULATION_FRACTION_FOR_MORE_VIBRANT = 0.75f;
+    private static final float POPULATION_FRACTION_FOR_MORE_VIBRANT = 1.0f;
+
+    /**
+     * Minimum saturation that a muted color must have if there exists if deciding between two
+     * colors
+     */
+    private static final float MIN_SATURATION_WHEN_DECIDING = 0.19f;
+
+    /**
+     * Minimum fraction that any color must have to be picked up as a text color
+     */
+    private static final double MINIMUM_IMAGE_FRACTION = 0.002;
+
+    /**
+     * The population fraction to select the dominant color as the text color over a the colored
+     * ones.
+     */
+    private static final float POPULATION_FRACTION_FOR_DOMINANT = 0.01f;
+
+    /**
+     * The population fraction to select a white or black color as the background over a color.
+     */
     private static final float POPULATION_FRACTION_FOR_WHITE_OR_BLACK = 2.5f;
     private static final float BLACK_MAX_LIGHTNESS = 0.08f;
-    private static final float WHITE_MIN_LIGHTNESS = 0.92f;
+    private static final float WHITE_MIN_LIGHTNESS = 0.90f;
     private static final int RESIZE_BITMAP_AREA = 150 * 150;
     private final ImageGradientColorizer mColorizer;
     private final Context mContext;
@@ -109,8 +129,11 @@
                         .resizeBitmapArea(RESIZE_BITMAP_AREA);
                 Palette palette = paletteBuilder.generate();
                 backgroundColor = findBackgroundColorAndFilter(palette);
-                // we want the full region again
-                paletteBuilder.setRegion(0, 0, bitmap.getWidth(), bitmap.getHeight());
+                // we want most of the full region again, slightly shifted to the right
+                float textColorStartWidthFraction = 0.4f;
+                paletteBuilder.setRegion((int) (bitmap.getWidth() * textColorStartWidthFraction), 0,
+                        bitmap.getWidth(),
+                        bitmap.getHeight());
                 if (mFilteredBackgroundHsl != null) {
                     paletteBuilder.addFilter((rgb, hsl) -> {
                         // at least 10 degrees hue difference
@@ -120,78 +143,7 @@
                 }
                 paletteBuilder.addFilter(mBlackWhiteFilter);
                 palette = paletteBuilder.generate();
-                int foregroundColor;
-                if (NotificationColorUtil.isColorLight(backgroundColor)) {
-                    Palette.Swatch first = palette.getDarkVibrantSwatch();
-                    Palette.Swatch second = palette.getVibrantSwatch();
-                    if (first != null && second != null) {
-                        int firstPopulation = first.getPopulation();
-                        int secondPopulation = second.getPopulation();
-                        if (firstPopulation / secondPopulation
-                                < POPULATION_FRACTION_FOR_MORE_VIBRANT) {
-                            foregroundColor = second.getRgb();
-                        } else {
-                            foregroundColor = first.getRgb();
-                        }
-                    } else if (first != null) {
-                        foregroundColor = first.getRgb();
-                    } else if (second != null) {
-                        foregroundColor = second.getRgb();
-                    } else {
-                        first = palette.getMutedSwatch();
-                        second = palette.getDarkMutedSwatch();
-                        if (first != null && second != null) {
-                            float firstSaturation = first.getHsl()[1];
-                            float secondSaturation = second.getHsl()[1];
-                            if (firstSaturation > secondSaturation) {
-                                foregroundColor = first.getRgb();
-                            } else {
-                                foregroundColor = second.getRgb();
-                            }
-                        } else if (first != null) {
-                            foregroundColor = first.getRgb();
-                        } else if (second != null) {
-                            foregroundColor = second.getRgb();
-                        } else {
-                            foregroundColor = Color.BLACK;
-                        }
-                    }
-                } else {
-                    Palette.Swatch first = palette.getLightVibrantSwatch();
-                    Palette.Swatch second = palette.getVibrantSwatch();
-                    if (first != null && second != null) {
-                        int firstPopulation = first.getPopulation();
-                        int secondPopulation = second.getPopulation();
-                        if (firstPopulation / secondPopulation
-                                < POPULATION_FRACTION_FOR_MORE_VIBRANT) {
-                            foregroundColor = second.getRgb();
-                        } else {
-                            foregroundColor = first.getRgb();
-                        }
-                    } else if (first != null) {
-                        foregroundColor = first.getRgb();
-                    } else if (second != null) {
-                        foregroundColor = second.getRgb();
-                    } else {
-                        first = palette.getMutedSwatch();
-                        second = palette.getLightMutedSwatch();
-                        if (first != null && second != null) {
-                            float firstSaturation = first.getHsl()[1];
-                            float secondSaturation = second.getHsl()[1];
-                            if (firstSaturation > secondSaturation) {
-                                foregroundColor = first.getRgb();
-                            } else {
-                                foregroundColor = second.getRgb();
-                            }
-                        } else if (first != null) {
-                            foregroundColor = first.getRgb();
-                        } else if (second != null) {
-                            foregroundColor = second.getRgb();
-                        } else {
-                            foregroundColor = Color.WHITE;
-                        }
-                    }
-                }
+                int foregroundColor = selectForegroundColor(backgroundColor, palette);
                 builder.setColorPalette(backgroundColor, foregroundColor);
             } else {
                 int id = mIsLowPriority
@@ -206,6 +158,95 @@
         }
     }
 
+    private int selectForegroundColor(int backgroundColor, Palette palette) {
+        if (NotificationColorUtil.isColorLight(backgroundColor)) {
+            return selectForegroundColorForSwatches(palette.getDarkVibrantSwatch(),
+                    palette.getVibrantSwatch(),
+                    palette.getDarkMutedSwatch(),
+                    palette.getMutedSwatch(),
+                    palette.getDominantSwatch(),
+                    Color.BLACK);
+        } else {
+            return selectForegroundColorForSwatches(palette.getLightVibrantSwatch(),
+                    palette.getVibrantSwatch(),
+                    palette.getLightMutedSwatch(),
+                    palette.getMutedSwatch(),
+                    palette.getDominantSwatch(),
+                    Color.WHITE);
+        }
+    }
+
+    private int selectForegroundColorForSwatches(Palette.Swatch moreVibrant,
+            Palette.Swatch vibrant, Palette.Swatch moreMutedSwatch, Palette.Swatch mutedSwatch,
+            Palette.Swatch dominantSwatch, int fallbackColor) {
+        Palette.Swatch coloredCandidate = selectVibrantCandidate(moreVibrant, vibrant);
+        if (coloredCandidate == null) {
+            coloredCandidate = selectMutedCandidate(mutedSwatch, moreMutedSwatch);
+        }
+        if (coloredCandidate != null) {
+            if (dominantSwatch == coloredCandidate) {
+                return coloredCandidate.getRgb();
+            } else if ((float) coloredCandidate.getPopulation() / dominantSwatch.getPopulation()
+                    < POPULATION_FRACTION_FOR_DOMINANT
+                    && dominantSwatch.getHsl()[1] > MIN_SATURATION_WHEN_DECIDING) {
+                return dominantSwatch.getRgb();
+            } else {
+                return coloredCandidate.getRgb();
+            }
+        } else if (hasEnoughPopulation(dominantSwatch)) {
+            return dominantSwatch.getRgb();
+        } else {
+            return fallbackColor;
+        }
+    }
+
+    private Palette.Swatch selectMutedCandidate(Palette.Swatch first,
+            Palette.Swatch second) {
+        boolean firstValid = hasEnoughPopulation(first);
+        boolean secondValid = hasEnoughPopulation(second);
+        if (firstValid && secondValid) {
+            float firstSaturation = first.getHsl()[1];
+            float secondSaturation = second.getHsl()[1];
+            float populationFraction = first.getPopulation() / (float) second.getPopulation();
+            if (firstSaturation * populationFraction > secondSaturation) {
+                return first;
+            } else {
+                return second;
+            }
+        } else if (firstValid) {
+            return first;
+        } else if (secondValid) {
+            return second;
+        }
+        return null;
+    }
+
+    private Palette.Swatch selectVibrantCandidate(Palette.Swatch first, Palette.Swatch second) {
+        boolean firstValid = hasEnoughPopulation(first);
+        boolean secondValid = hasEnoughPopulation(second);
+        if (firstValid && secondValid) {
+            int firstPopulation = first.getPopulation();
+            int secondPopulation = second.getPopulation();
+            if (firstPopulation / (float) secondPopulation
+                    < POPULATION_FRACTION_FOR_MORE_VIBRANT) {
+                return second;
+            } else {
+                return first;
+            }
+        } else if (firstValid) {
+            return first;
+        } else if (secondValid) {
+            return second;
+        }
+        return null;
+    }
+
+    private boolean hasEnoughPopulation(Palette.Swatch swatch) {
+        // We want a fraction that is at least 1% of the image
+        return swatch != null
+                && (swatch.getPopulation() / (float) RESIZE_BITMAP_AREA > MINIMUM_IMAGE_FRACTION);
+    }
+
     private int findBackgroundColorAndFilter(Palette palette) {
         // by default we use the dominant palette
         Palette.Swatch dominantSwatch = palette.getDominantSwatch();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 2124011..95f32bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -18,6 +18,7 @@
 
 import android.app.ActivityManager;
 import android.content.Context;
+import android.os.Handler;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.Slog;
@@ -55,6 +56,7 @@
     protected final ViewGroup mContainer;
     private final FalsingManager mFalsingManager;
     private final DismissCallbackRegistry mDismissCallbackRegistry;
+    private final Handler mHandler;
     protected KeyguardHostView mKeyguardView;
     protected ViewGroup mRoot;
     private boolean mShowingSoon;
@@ -66,6 +68,7 @@
                     mBouncerPromptReason = mCallback.getBouncerPromptReason();
                 }
             };
+    private final Runnable mRemoveViewRunnable = this::removeView;
 
     public KeyguardBouncer(Context context, ViewMediatorCallback callback,
             LockPatternUtils lockPatternUtils, ViewGroup container,
@@ -77,6 +80,7 @@
         KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
         mFalsingManager = FalsingManager.getInstance(mContext);
         mDismissCallbackRegistry = dismissCallbackRegistry;
+        mHandler = new Handler();
     }
 
     public void show(boolean resetSecuritySelection) {
@@ -179,10 +183,14 @@
             mKeyguardView.cancelDismissAction();
             mKeyguardView.cleanUp();
         }
-        if (destroyView) {
-            removeView();
-        } else if (mRoot != null) {
+        if (mRoot != null) {
             mRoot.setVisibility(View.INVISIBLE);
+            if (destroyView) {
+
+                // We have a ViewFlipper that unregisters a broadcast when being detached, which may
+                // be slow because of AM lock contention during unlocking. We can delay it a bit.
+                mHandler.postDelayed(mRemoveViewRunnable, 50);
+            }
         }
     }
 
@@ -226,6 +234,7 @@
     }
 
     protected void ensureView() {
+        mHandler.removeCallbacks(mRemoveViewRunnable);
         if (mRoot == null) {
             inflateView();
         }
@@ -233,6 +242,7 @@
 
     protected void inflateView() {
         removeView();
+        mHandler.removeCallbacks(mRemoveViewRunnable);
         mRoot = (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.keyguard_bouncer, null);
         mKeyguardView = (KeyguardHostView) mRoot.findViewById(R.id.keyguard_host_view);
         mKeyguardView.setLockPatternUtils(mLockPatternUtils);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 4581204..52838b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -128,8 +128,7 @@
 
     protected boolean shouldShowNotificationIcon(NotificationData.Entry entry,
             NotificationData notificationData, boolean showAmbient) {
-        if (notificationData.isAmbient(entry.key) && !showAmbient
-                && !NotificationData.showNotificationEvenIfUnprovisioned(entry.notification)) {
+        if (notificationData.isAmbient(entry.key) && !showAmbient) {
             return false;
         }
         if (!StatusBar.isTopLevelChild(entry)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index e378e871..9d1d038 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -34,10 +34,9 @@
 import android.widget.FrameLayout;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.DejankUtils;
-import com.android.systemui.EventLogTags;
-import com.android.systemui.Interpolators;
 import com.android.keyguard.LatencyTracker;
+import com.android.systemui.DejankUtils;
+import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.doze.DozeLog;
@@ -833,6 +832,14 @@
             }
         }
 
+        // If we are closing the panel and we are almost there due to a slow decelerating
+        // interpolator, abort the animation.
+        if (mExpandedHeight < 1f && mExpandedHeight != 0f && mClosing) {
+            mExpandedHeight = 0f;
+            if (mHeightAnimator != null) {
+                mHeightAnimator.end();
+            }
+        }
         mExpandedFraction = Math.min(1f,
                 fhWithoutOverExpansion == 0 ? 0 : mExpandedHeight / fhWithoutOverExpansion);
         onHeightUpdated(mExpandedHeight);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 41fb5f7..f3ba5aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -58,6 +58,7 @@
 import com.android.systemui.DockedStackExistsListener;
 import com.android.systemui.R;
 import com.android.systemui.SysUiServiceProvider;
+import com.android.systemui.UiOffloadThread;
 import com.android.systemui.qs.tiles.DndTile;
 import com.android.systemui.qs.tiles.RotationLockTile;
 import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -128,6 +129,7 @@
     private final KeyguardMonitor mKeyguardMonitor;
     private final LocationController mLocationController;
     private final ArraySet<Pair<String, Integer>> mCurrentNotifs = new ArraySet<>();
+    private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
 
     // Assume it's all good unless we hear otherwise.  We don't always seem
     // to get broadcasts that it *is* there.
@@ -472,30 +474,38 @@
     }
 
     private void updateManagedProfile() {
-        try {
-            final boolean showIcon;
-            final int userId = ActivityManager.getService().getLastResumedActivityUserId();
-            if (mUserManager.isManagedProfile(userId) && !mKeyguardMonitor.isShowing()) {
-                showIcon = true;
-                mIconController.setIcon(mSlotManagedProfile,
-                        R.drawable.stat_sys_managed_profile_status,
-                        mContext.getString(R.string.accessibility_managed_profile));
-            } else if (mManagedProfileInQuietMode) {
-                showIcon = true;
-                mIconController.setIcon(mSlotManagedProfile,
-                        R.drawable.stat_sys_managed_profile_status_off,
-                        mContext.getString(R.string.accessibility_managed_profile));
-            } else {
-                showIcon = false;
+        // getLastResumedActivityUserId needds to acquire the AM lock, which may be contended in
+        // some cases. Since it doesn't really matter here whether it's updated in this frame
+        // or in the next one, we call this method from our UI offload thread.
+        mUiOffloadThread.submit(() -> {
+            final int userId;
+            try {
+                userId = ActivityManager.getService().getLastResumedActivityUserId();
+                boolean isManagedProfile = mUserManager.isManagedProfile(userId);
+                mHandler.post(() -> {
+                    final boolean showIcon;
+                    if (isManagedProfile && !mKeyguardMonitor.isShowing()) {
+                        showIcon = true;
+                        mIconController.setIcon(mSlotManagedProfile,
+                                R.drawable.stat_sys_managed_profile_status,
+                                mContext.getString(R.string.accessibility_managed_profile));
+                    } else if (mManagedProfileInQuietMode) {
+                        showIcon = true;
+                        mIconController.setIcon(mSlotManagedProfile,
+                                R.drawable.stat_sys_managed_profile_status_off,
+                                mContext.getString(R.string.accessibility_managed_profile));
+                    } else {
+                        showIcon = false;
+                    }
+                    if (mManagedProfileIconVisible != showIcon) {
+                        mIconController.setIconVisibility(mSlotManagedProfile, showIcon);
+                        mManagedProfileIconVisible = showIcon;
+                    }
+                });
+            } catch (RemoteException e) {
+                Log.w(TAG, "updateManagedProfile: ", e);
             }
-            if (mManagedProfileIconVisible != showIcon) {
-                mIconController.setIconVisibility(mSlotManagedProfile, showIcon);
-                mManagedProfileIconVisible = showIcon;
-            }
-        } catch (RemoteException ex) {
-            Log.w(TAG, "updateManagedProfile: ", ex);
-            // ignore
-        }
+        });
     }
 
     private void updateForegroundInstantApps() {
@@ -503,26 +513,22 @@
         ArraySet<Pair<String, Integer>> notifs = new ArraySet<>(mCurrentNotifs);
         IPackageManager pm = AppGlobals.getPackageManager();
         mCurrentNotifs.clear();
-        try {
-            ArraySet<Integer> stacksToCheck = new ArraySet<>();
-            int[] STACKS_TO_CHECK = new int[]{
-                    StackId.FULLSCREEN_WORKSPACE_STACK_ID,
-                    StackId.DOCKED_STACK_ID,
-            };
-            int focusedId = ActivityManager.getService().getFocusedStackId();
-            if (focusedId == StackId.FULLSCREEN_WORKSPACE_STACK_ID
-                    || focusedId == StackId.FULLSCREEN_WORKSPACE_STACK_ID) {
-                checkStack(StackId.FULLSCREEN_WORKSPACE_STACK_ID, notifs, noMan, pm);
+        mUiOffloadThread.submit(() -> {
+            try {
+                int focusedId = ActivityManager.getService().getFocusedStackId();
+                if (focusedId == StackId.FULLSCREEN_WORKSPACE_STACK_ID) {
+                    checkStack(StackId.FULLSCREEN_WORKSPACE_STACK_ID, notifs, noMan, pm);
+                }
+                if (mDockedStackExists) {
+                    checkStack(StackId.DOCKED_STACK_ID, notifs, noMan, pm);
+                }
+            } catch (RemoteException e) {
+                e.rethrowFromSystemServer();
             }
-            if (mDockedStackExists) {
-                checkStack(StackId.DOCKED_STACK_ID, notifs, noMan, pm);
-            }
-        } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
-        }
-        // Cancel all the leftover notifications that don't have a foreground process anymore.
-        notifs.forEach(v -> noMan.cancelAsUser(v.first, SystemMessage.NOTE_INSTANT_APPS,
-                new UserHandle(v.second)));
+            // Cancel all the leftover notifications that don't have a foreground process anymore.
+            notifs.forEach(v -> noMan.cancelAsUser(v.first, SystemMessage.NOTE_INSTANT_APPS,
+                    new UserHandle(v.second)));
+        });
     }
 
     private void checkStack(int stackId, ArraySet<Pair<String, Integer>> notifs,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 916b603..970d1de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -121,12 +121,12 @@
     public void onPanelCollapsed() {
         super.onPanelCollapsed();
         // Close the status bar in the next frame so we can show the end of the animation.
-        DejankUtils.postAfterTraversal(mHideExpandedRunnable);
+        post(mHideExpandedRunnable);
         mIsFullyOpenedPanel = false;
     }
 
     public void removePendingHideExpandedRunnables() {
-        DejankUtils.removeCallbacks(mHideExpandedRunnable);
+        removeCallbacks(mHideExpandedRunnable);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 1799bc9..4541d07 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.graphics.Color;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.support.v4.graphics.ColorUtils;
 import android.util.Log;
 import android.util.TypedValue;
@@ -260,6 +261,14 @@
                 : SCRIM_IN_FRONT_ALPHA;
     }
 
+    /**
+     * Sets the given drawable as the background of the scrim that shows up behind the
+     * notifications.
+     */
+    public void setScrimBehindDrawable(Drawable drawable) {
+        mScrimBehind.setDrawable(drawable);
+    }
+
     protected void scheduleUpdate() {
         if (mUpdatePending) return;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 805450e..01bab3f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -95,6 +95,7 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.SystemService;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -164,6 +165,7 @@
 import com.android.systemui.SwipeHelper;
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIFactory;
+import com.android.systemui.UiOffloadThread;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.classifier.FalsingLog;
 import com.android.systemui.classifier.FalsingManager;
@@ -184,6 +186,7 @@
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
 import com.android.systemui.recents.events.activity.UndockingTaskEvent;
+import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.stackdivider.WindowManagerProxy;
 import com.android.systemui.statusbar.ActivatableNotificationView;
@@ -545,6 +548,7 @@
     private ViewMediatorCallback mKeyguardViewMediatorCallback;
     protected ScrimController mScrimController;
     protected DozeScrimController mDozeScrimController;
+    private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
 
     private final Runnable mAutohide = new Runnable() {
         @Override
@@ -716,7 +720,7 @@
     private NetworkController mNetworkController;
     private KeyguardMonitorImpl mKeyguardMonitor;
     private BatteryController mBatteryController;
-    private boolean mPanelExpanded;
+    protected boolean mPanelExpanded;
     private boolean mKeyguardRequested;
     private boolean mIsKeyguard;
     private LogMaker mStatusBarStateLog;
@@ -792,8 +796,6 @@
         mAccessibilityManager = (AccessibilityManager)
                 mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
 
-        mDreamManager = IDreamManager.Stub.asInterface(
-                ServiceManager.checkService(DreamService.DREAM_SERVICE));
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
 
         mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
@@ -1019,12 +1021,6 @@
                 new IconManager((ViewGroup) mKeyguardStatusBar.findViewById(R.id.statusIcons)));
         mIconController = Dependency.get(StatusBarIconController.class);
 
-        if (!ActivityManager.isHighEndGfx()) {
-            mStatusBarWindow.setBackground(null);
-            mNotificationPanel.setBackground(new FastColorDrawable(context.getColor(
-                    R.color.notification_panel_solid_background)));
-        }
-
         mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow, mGroupManager);
         mHeadsUpManager.setBar(this);
         mHeadsUpManager.addListener(this);
@@ -1550,13 +1546,7 @@
     }
 
     void awakenDreams() {
-        if (mDreamManager != null) {
-            try {
-                mDreamManager.awaken();
-            } catch (RemoteException e) {
-                // fine, stay asleep then
-            }
-        }
+        SystemServicesProxy.getInstance(mContext).awakenDreamsAsync();
     }
 
     public UserHandle getCurrentUserHandle() {
@@ -4407,7 +4397,7 @@
         checkBarModes();
         updateMediaMetaData(false, mState != StatusBarState.KEYGUARD);
         mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
-                mStatusBarKeyguardViewManager.isSecure(),
+                mUnlockMethodCache.isMethodSecure(),
                 mStatusBarKeyguardViewManager.isOccluded());
         Trace.endSection();
     }
@@ -5243,7 +5233,6 @@
     protected boolean mDisableNotificationAlerts = false;
 
     protected DevicePolicyManager mDevicePolicyManager;
-    protected IDreamManager mDreamManager;
     protected PowerManager mPowerManager;
     protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
 
@@ -6909,12 +6898,8 @@
             return false;
         }
 
-        boolean inUse = mPowerManager.isScreenOn();
-        try {
-            inUse = inUse && !mDreamManager.isDreaming();
-        } catch (RemoteException e) {
-            Log.d(TAG, "failed to query dream manager", e);
-        }
+        boolean inUse = mPowerManager.isScreenOn()
+                && !SystemServicesProxy.getInstance(mContext).isDreaming();
 
         if (!inUse && !isDozing()) {
             if (DEBUG) {
@@ -6991,11 +6976,13 @@
 
     @Override
     public void logNotificationExpansion(String key, boolean userAction, boolean expanded) {
-        try {
-            mBarService.onNotificationExpansionChanged(key, userAction, expanded);
-        } catch (RemoteException e) {
-            // Ignore.
-        }
+        mUiOffloadThread.submit(() -> {
+            try {
+                mBarService.onNotificationExpansionChanged(key, userAction, expanded);
+            } catch (RemoteException e) {
+                // Ignore.
+            }
+        });
     }
 
     public boolean isKeyguardSecure() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
index cfaca0d..f2283a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
@@ -102,15 +102,21 @@
     }
 
     private void notifyUserChanged() {
-        mListeners.forEach(c -> c.onUserSwitched());
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onUserSwitched();
+        }
     }
 
     private void notifySetupChanged() {
-        mListeners.forEach(c -> c.onUserSetupChanged());
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onUserSetupChanged();
+        }
     }
 
     private void notifyProvisionedChanged() {
-        mListeners.forEach(c -> c.onDeviceProvisionedChanged());
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onDeviceProvisionedChanged();
+        }
     }
 
     protected final ContentObserver mSettingsObserver = new ContentObserver(Dependency.get(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 5f7ac5d..70f2260 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -257,6 +257,12 @@
         mEntryPool.release(remove);
     }
 
+    public void removeAllHeadsUpEntries() {
+        for (String key : mHeadsUpEntries.keySet()) {
+            removeHeadsUpEntry(mHeadsUpEntries.get(key).entry);
+        }
+    }
+
     private void updatePinnedMode() {
         boolean hasPinnedNotification = hasPinnedNotificationInternal();
         if (hasPinnedNotification == mHasPinnedNotification) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
index d6c080a..7bce33a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
@@ -124,13 +124,11 @@
         mKeyguardFadingAway = true;
         mKeyguardFadingAwayDelay = delay;
         mKeyguardFadingAwayDuration = fadeoutDuration;
-        notifyKeyguardChanged();
     }
 
     public void notifyKeyguardDoneFading() {
         mKeyguardFadingAway = false;
         mKeyguardGoingAway = false;
-        notifyKeyguardChanged();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 53671a1..e1acc9b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -872,7 +872,14 @@
     private final KeyguardMonitor.Callback mCallback = new KeyguardMonitor.Callback() {
         @Override
         public void onKeyguardShowingChanged() {
-            notifyAdapters();
+
+            // When Keyguard is going away, we don't need to update our items immediately which
+            // helps making the transition faster.
+            if (!mKeyguardMonitor.isShowing()) {
+                mHandler.post(UserSwitcherController.this::notifyAdapters);
+            } else {
+                notifyAdapters();
+            }
         }
     };
 
diff --git a/packages/SystemUI/tests/AndroidTest.xml b/packages/SystemUI/tests/AndroidTest.xml
index 6d5ef73..6ca42e8 100644
--- a/packages/SystemUI/tests/AndroidTest.xml
+++ b/packages/SystemUI/tests/AndroidTest.xml
@@ -19,6 +19,7 @@
     </target_preparer>
 
     <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="framework-base-presubmit" />
     <option name="test-tag" value="SystemUITests" />
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.systemui.tests" />
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index aadae0f..0aac1c0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -21,15 +21,21 @@
 import android.os.MessageQueue;
 import android.support.test.InstrumentationRegistry;
 import android.testing.LeakCheck;
+import android.util.Log;
 
 import org.junit.Before;
 import org.junit.Rule;
 
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
 /**
  * Base class that does System UI specific setup.
  */
 public abstract class SysuiTestCase {
 
+    private static final String TAG = "SysuiTestCase";
+
     private Handler mHandler;
     @Rule
     public SysuiTestableContext mContext = new SysuiTestableContext(
@@ -57,6 +63,15 @@
         waitForIdleSync(mHandler);
     }
 
+    protected void waitForUiOffloadThread() {
+        Future<?> future = Dependency.get(UiOffloadThread.class).submit(() -> {});
+        try {
+            future.get();
+        } catch (InterruptedException | ExecutionException e) {
+            Log.e(TAG, "Failed to wait for ui offload thread.", e);
+        }
+    }
+
     public static void waitForIdleSync(Handler h) {
         validateThread(h.getLooper());
         Idler idler = new Idler(null);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/DismissCallbackRegistryTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/DismissCallbackRegistryTest.java
index 131a70b..308670d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/DismissCallbackRegistryTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/DismissCallbackRegistryTest.java
@@ -23,6 +23,8 @@
 import android.support.test.runner.AndroidJUnit4;
 
 import com.android.internal.policy.IKeyguardDismissCallback;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.UiOffloadThread;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -35,7 +37,7 @@
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class DismissCallbackRegistryTest {
+public class DismissCallbackRegistryTest extends SysuiTestCase {
 
     private final DismissCallbackRegistry mDismissCallbackRegistry = new DismissCallbackRegistry();
     private @Mock IKeyguardDismissCallback mMockCallback;
@@ -50,6 +52,7 @@
     public void testCancelled() throws Exception {
         mDismissCallbackRegistry.addCallback(mMockCallback);
         mDismissCallbackRegistry.notifyDismissCancelled();
+        waitForUiOffloadThread();
         verify(mMockCallback).onDismissCancelled();
     }
 
@@ -58,6 +61,7 @@
         mDismissCallbackRegistry.addCallback(mMockCallback);
         mDismissCallbackRegistry.addCallback(mMockCallback2);
         mDismissCallbackRegistry.notifyDismissCancelled();
+        waitForUiOffloadThread();
         verify(mMockCallback).onDismissCancelled();
         verify(mMockCallback2).onDismissCancelled();
     }
@@ -66,6 +70,7 @@
     public void testSucceeded() throws Exception {
         mDismissCallbackRegistry.addCallback(mMockCallback);
         mDismissCallbackRegistry.notifyDismissSucceeded();
+        waitForUiOffloadThread();
         verify(mMockCallback).onDismissSucceeded();
     }
 
@@ -74,6 +79,7 @@
         mDismissCallbackRegistry.addCallback(mMockCallback);
         mDismissCallbackRegistry.addCallback(mMockCallback2);
         mDismissCallbackRegistry.notifyDismissSucceeded();
+        waitForUiOffloadThread();
         verify(mMockCallback).onDismissSucceeded();
         verify(mMockCallback2).onDismissSucceeded();
     }
@@ -83,6 +89,7 @@
         mDismissCallbackRegistry.addCallback(mMockCallback);
         mDismissCallbackRegistry.notifyDismissSucceeded();
         mDismissCallbackRegistry.notifyDismissSucceeded();
+        waitForUiOffloadThread();
         verify(mMockCallback, times(1)).onDismissSucceeded();
     }
 }
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 818f478..f519db8 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3979,6 +3979,11 @@
     // OS: O
     ACTION_CAMERA_LIFT_TRIGGER = 989;
 
+    // OPEN: Choose screen lock dialog in Settings
+    // CATEGORY: SETTINGS
+    // OS: O DR
+    SETTINGS_CHOOSE_LOCK_DIALOG = 990;
+
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
   }
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index debb157..564d135 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -241,6 +241,20 @@
 
   // List of events
   repeated StaEvent sta_event_list = 52;
+
+  // Total number of times WiFi HAL crashed.
+  optional int32 num_hal_crashes = 53;
+
+  // Total number of times WiFicond crashed.
+  optional int32 num_wificond_crashes = 54;
+
+  // Indicates the number of times an error was encountered in
+  // Wifi HAL when wifi was turned on.
+  optional int32 num_wifi_on_failure_due_to_hal = 55;
+
+  // Indicates the number of times an error was encountered in
+  // Wificond when wifi was turned on.
+  optional int32 num_wifi_on_failure_due_to_wificond = 56;
 }
 
 // Information that gets logged for every WiFi connection.
diff --git a/services/accessibility/java/com/android/server/accessibility/ActionReplacingCallback.java b/services/accessibility/java/com/android/server/accessibility/ActionReplacingCallback.java
index 0e30fb2..de8a518 100644
--- a/services/accessibility/java/com/android/server/accessibility/ActionReplacingCallback.java
+++ b/services/accessibility/java/com/android/server/accessibility/ActionReplacingCallback.java
@@ -26,6 +26,7 @@
 import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
 import com.android.internal.annotations.GuardedBy;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -96,7 +97,7 @@
                 mNodeFromOriginalWindow = info;
             } else {
                 Slog.e(LOG_TAG, "Callback with unexpected interactionId");
-                throw new RuntimeException("Callback with unexpected interactionId"); // Remove
+                return;
             }
 
             mSingleNodeCallbackHappened = true;
@@ -119,7 +120,7 @@
                 mNodesWithReplacementActions = infos;
             } else {
                 Slog.e(LOG_TAG, "Callback with unexpected interactionId");
-                throw new RuntimeException("Callback with unexpected interactionId"); // Remove
+                return;
             }
             callbackForSingleNode = mSingleNodeCallbackHappened;
             callbackForMultipleNodes = mMultiNodeCallbackHappened;
@@ -147,7 +148,7 @@
                 if (DEBUG) {
                     Slog.e(LOG_TAG, "Extra callback");
                 }
-                throw new RuntimeException("Extra callback"); // Replace with return before submit
+                return;
             }
             if (mNodeFromOriginalWindow != null) {
                 replaceActionsOnInfoLocked(mNodeFromOriginalWindow);
@@ -172,7 +173,7 @@
                 if (DEBUG) {
                     Slog.e(LOG_TAG, "Extra callback");
                 }
-                throw new RuntimeException("Extra callback"); // Replace with return before submit
+                return;
             }
             if (mNodesFromOriginalWindow != null) {
                 for (int i = 0; i < mNodesFromOriginalWindow.size(); i++) {
@@ -180,7 +181,8 @@
                 }
             }
             recycleReplaceActionNodesLocked();
-            nodesToReturn = mNodesFromOriginalWindow;
+            nodesToReturn = (mNodesFromOriginalWindow == null)
+                    ? null : new ArrayList<>(mNodesFromOriginalWindow);
             mDone = true;
         }
         try {
@@ -195,6 +197,12 @@
     @GuardedBy("mLock")
     private void replaceActionsOnInfoLocked(AccessibilityNodeInfo info) {
         info.removeAllActions();
+        info.setClickable(false);
+        info.setFocusable(false);
+        info.setContextClickable(false);
+        info.setScrollable(false);
+        info.setLongClickable(false);
+        info.setDismissable(false);
         // We currently only replace actions for the root node
         if ((info.getSourceNodeId() == AccessibilityNodeInfo.ROOT_NODE_ID)
                 && mNodesWithReplacementActions != null) {
@@ -213,6 +221,12 @@
                         info.addAction(AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS);
                         info.addAction(AccessibilityAction.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
                     }
+                    info.setClickable(nodeWithReplacementActions.isClickable());
+                    info.setFocusable(nodeWithReplacementActions.isFocusable());
+                    info.setContextClickable(nodeWithReplacementActions.isContextClickable());
+                    info.setScrollable(nodeWithReplacementActions.isScrollable());
+                    info.setLongClickable(nodeWithReplacementActions.isLongClickable());
+                    info.setDismissable(nodeWithReplacementActions.isDismissable());
                 }
             }
         }
@@ -220,6 +234,7 @@
 
     @GuardedBy("mLock")
     private void recycleReplaceActionNodesLocked() {
+        if (mNodesWithReplacementActions == null) return;
         for (int i = mNodesWithReplacementActions.size() - 1; i >= 0; i--) {
             AccessibilityNodeInfo nodeWithReplacementAction = mNodesWithReplacementActions.get(i);
             nodeWithReplacementAction.recycle();
diff --git a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
index 6e87f88..e380f2c 100644
--- a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
@@ -938,7 +938,12 @@
         if (pointerIdBits == ALL_POINTER_ID_BITS) {
             event = prototype;
         } else {
-            event = prototype.split(pointerIdBits);
+            try {
+                event = prototype.split(pointerIdBits);
+            } catch (IllegalArgumentException e) {
+                Slog.e(LOG_TAG, "sendMotionEvent: Failed to split motion event: " + e);
+                return;
+            }
         }
         if (action == MotionEvent.ACTION_DOWN) {
             event.setDownTime(event.getEventTime());
diff --git a/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java b/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
index ff92340..b3e20dc 100644
--- a/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
@@ -17,15 +17,18 @@
 package com.android.server.backup.utils;
 
 import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_VERSION;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
 
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.Signature;
 import android.os.Build;
 import android.os.ParcelFileDescriptor;
+import android.util.Slog;
 import android.util.StringBuilderPrinter;
 
 import java.io.DataInputStream;
+import java.io.EOFException;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -55,6 +58,10 @@
             while (chunkTotal > 0) {
                 int toRead = (chunkTotal > buffer.length) ? buffer.length : chunkTotal;
                 int nRead = in.read(buffer, 0, toRead);
+                if (nRead < 0) {
+                    Slog.e(TAG, "Unexpectedly reached end of file while reading data");
+                    throw new EOFException();
+                }
                 out.write(buffer, 0, nRead);
                 chunkTotal -= nRead;
             }
diff --git a/services/core/Android.mk b/services/core/Android.mk
index 20a699b..4d080e9 100644
--- a/services/core/Android.mk
+++ b/services/core/Android.mk
@@ -31,6 +31,7 @@
     android.hardware.weaver-V1.0-java-static \
     android.hardware.biometrics.fingerprint-V2.1-java-static \
     android.hardware.oemlock-V1.0-java-static \
+    android.hardware.tetheroffload.control-V1.0-java-static \
     android.hardware.vibrator-V1.0-java-constants \
 
 ifneq ($(INCREMENTAL_BUILDS),)
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index b65f54e..61057dd 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -1697,7 +1697,7 @@
                     mHandler.removeMessages(MESSAGE_USER_SWITCHED);
 
                     /* disable and enable BT when detect a user switch */
-                    if (mEnable && mBluetooth != null) {
+                    if (mBluetooth != null && isEnabled()) {
                         try {
                             mBluetoothLock.readLock().lock();
                             if (mBluetooth != null) {
@@ -1766,6 +1766,8 @@
                         mState = BluetoothAdapter.STATE_OFF;
                         // enable
                         addActiveLog(REASON_USER_SWITCH, true);
+                        // mEnable flag could have been reset on disableBLE. Reenable it.
+                        mEnable = true;
                         handleEnable(mQuietEnable);
                     } else if (mBinding || mBluetooth != null) {
                         Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED);
diff --git a/services/core/java/com/android/server/CommonTimeManagementService.java b/services/core/java/com/android/server/CommonTimeManagementService.java
index 07c8679..5cebfa5 100644
--- a/services/core/java/com/android/server/CommonTimeManagementService.java
+++ b/services/core/java/com/android/server/CommonTimeManagementService.java
@@ -92,12 +92,12 @@
      * Internal state
      */
     private final Context mContext;
+    private final Object mLock = new Object();
     private INetworkManagementService mNetMgr;
     private CommonTimeConfig mCTConfig;
     private String mCurIface;
     private Handler mReconnectHandler = new Handler();
     private Handler mNoInterfaceHandler = new Handler();
-    private Object mLock = new Object();
     private boolean mDetectedAtStartup = false;
     private byte mEffectivePrio = BASE_SERVER_PRIO;
 
@@ -105,15 +105,19 @@
      * Callback handler implementations.
      */
     private INetworkManagementEventObserver mIfaceObserver = new BaseNetworkObserver() {
+        @Override
         public void interfaceStatusChanged(String iface, boolean up) {
             reevaluateServiceState();
         }
+        @Override
         public void interfaceLinkStateChanged(String iface, boolean up) {
             reevaluateServiceState();
         }
+        @Override
         public void interfaceAdded(String iface) {
             reevaluateServiceState();
         }
+        @Override
         public void interfaceRemoved(String iface) {
             reevaluateServiceState();
         }
@@ -127,19 +131,11 @@
     };
 
     private CommonTimeConfig.OnServerDiedListener mCTServerDiedListener =
-        new CommonTimeConfig.OnServerDiedListener() {
-            public void onServerDied() {
-                scheduleTimeConfigReconnect();
-            }
-        };
+            () -> scheduleTimeConfigReconnect();
 
-    private Runnable mReconnectRunnable = new Runnable() {
-        public void run() { connectToTimeConfig(); }
-    };
+    private Runnable mReconnectRunnable = () -> connectToTimeConfig();
 
-    private Runnable mNoInterfaceRunnable = new Runnable() {
-        public void run() { handleNoInterfaceTimeout(); }
-    };
+    private Runnable mNoInterfaceRunnable = () -> handleNoInterfaceTimeout();
 
     /*
      * Public interface (constructor, systemReady and dump)
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 688c231..b4f27f5 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -139,6 +139,7 @@
 import com.android.server.connectivity.PacManager;
 import com.android.server.connectivity.PermissionMonitor;
 import com.android.server.connectivity.Tethering;
+import com.android.server.connectivity.tethering.TetheringDependencies;
 import com.android.server.connectivity.Vpn;
 import com.android.server.net.BaseNetworkObserver;
 import com.android.server.net.LockdownVpnTracker;
@@ -177,6 +178,9 @@
         implements PendingIntent.OnFinished {
     private static final String TAG = ConnectivityService.class.getSimpleName();
 
+    public static final String DIAG_ARG = "--diag";
+    public static final String SHORT_ARG = "--short";
+
     private static final boolean DBG = true;
     private static final boolean VDBG = false;
 
@@ -789,8 +793,7 @@
         mTestMode = mSystemProperties.get("cm.test.mode").equals("true")
                 && mSystemProperties.get("ro.build.type").equals("eng");
 
-        mTethering = new Tethering(mContext, mNetd, statsService, mPolicyManager,
-                                   IoThread.get().getLooper(), new MockableSystemProperties());
+        mTethering = makeTethering();
 
         mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
 
@@ -840,6 +843,14 @@
         mMultinetworkPolicyTracker.start();
     }
 
+    private Tethering makeTethering() {
+        // TODO: Move other elements into @Overridden getters.
+        final TetheringDependencies deps = new TetheringDependencies();
+        return new Tethering(mContext, mNetd, mStatsService, mPolicyManager,
+                IoThread.get().getLooper(), new MockableSystemProperties(),
+                deps);
+    }
+
     private NetworkRequest createInternetRequestForTransport(
             int transportType, NetworkRequest.Type type) {
         NetworkCapabilities netCap = new NetworkCapabilities();
@@ -1852,7 +1863,7 @@
         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
-        if (argsContain(args, "--diag")) {
+        if (argsContain(args, DIAG_ARG)) {
             dumpNetworkDiagnostics(pw);
             return;
         }
@@ -1917,7 +1928,7 @@
         pw.println();
         dumpAvoidBadWifiSettings(pw);
 
-        if (argsContain(args, "--short") == false) {
+        if (argsContain(args, SHORT_ARG) == false) {
             pw.println();
             synchronized (mValidationLogs) {
                 pw.println("mValidationLogs (most recent first):");
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index 6c44cc8..47f157d 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -17,6 +17,7 @@
 package com.android.server;
 
 import android.app.ActivityManager;
+import android.app.KeyguardManager;
 import android.app.StatusBarManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -28,6 +29,8 @@
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
+import android.hardware.TriggerEvent;
+import android.hardware.TriggerEventListener;
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
@@ -78,6 +81,8 @@
     private Sensor mCameraLiftTriggerSensor;
     private Context mContext;
     private final MetricsLogger mMetricsLogger;
+    private PowerManager mPowerManager;
+    private KeyguardManager mKeyguardManager;
 
     /** The wake lock held when a gesture is detected. */
     private WakeLock mWakeLock;
@@ -145,9 +150,11 @@
                 return;
             }
 
-            PowerManager powerManager = (PowerManager) mContext.getSystemService(
+            mKeyguardManager = (KeyguardManager) mContext.getSystemService(
+                    Context.KEYGUARD_SERVICE);
+            mPowerManager = (PowerManager) mContext.getSystemService(
                     Context.POWER_SERVICE);
-            mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+            mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                     "GestureLauncherService");
             updateCameraRegistered();
             updateCameraDoubleTapPowerEnabled();
@@ -255,7 +262,7 @@
 
             SensorManager sensorManager = (SensorManager) mContext.getSystemService(
                     Context.SENSOR_SERVICE);
-            sensorManager.unregisterListener(mCameraLiftTriggerListener);
+            sensorManager.cancelTriggerSensor(mCameraLiftTriggerListener, mCameraLiftTriggerSensor);
         }
     }
 
@@ -276,15 +283,15 @@
                 com.android.internal.R.string.config_cameraLiftTriggerSensorStringType);
             mCameraLiftTriggerSensor = sensorManager.getDefaultSensor(
                     cameraLiftTriggerId,
-                    false /*wakeUp*/);
+                    true /*wakeUp*/);
 
             // Compare the camera lift trigger string type to that in the resource file to make
             // sure we are registering the correct sensor. This is redundant check, it
             // makes the code more robust.
             if (mCameraLiftTriggerSensor != null) {
                 if (sensorName.equals(mCameraLiftTriggerSensor.getStringType())) {
-                    mCameraLiftRegistered = sensorManager.registerListener(mCameraLiftTriggerListener,
-                            mCameraLiftTriggerSensor, 0);
+                    mCameraLiftRegistered = sensorManager.requestTriggerSensor(mCameraLiftTriggerListener,
+                            mCameraLiftTriggerSensor);
                 } else {
                     String message = String.format("Wrong configuration. Sensor type and sensor "
                             + "string type don't match: %s in resources, %s in the sensor.",
@@ -506,30 +513,38 @@
         }
     }
 
-    private final class CameraLiftTriggerEventListener implements SensorEventListener {
+    private final class CameraLiftTriggerEventListener extends TriggerEventListener {
         @Override
-        public void onSensorChanged(SensorEvent event) {
+        public void onTrigger(TriggerEvent event) {
             if (!mCameraLiftRegistered) {
               if (DBG) Slog.d(TAG, "Ignoring camera lift event because it's unregistered.");
               return;
             }
             if (event.sensor == mCameraLiftTriggerSensor) {
+                Resources resources = mContext.getResources();
+                SensorManager sensorManager = (SensorManager) mContext.getSystemService(
+                        Context.SENSOR_SERVICE);
+
                 if (DBG) {
                     float[] values = event.values;
                     Slog.d(TAG, String.format("Received a camera lift trigger event: " +
                             "values=[%.4f].", values[0]));
                 }
-                if (handleCameraGesture(true /* useWakelock */,
-                        StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER)) {
-                    MetricsLogger.action(mContext, MetricsEvent.ACTION_CAMERA_LIFT_TRIGGER);
+                if (mKeyguardManager.isKeyguardLocked() || !mPowerManager.isInteractive()) {
+                    if (handleCameraGesture(true /* useWakelock */,
+                            StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER)) {
+                        MetricsLogger.action(mContext, MetricsEvent.ACTION_CAMERA_LIFT_TRIGGER);
+                    }
+                } else if (DBG) {
+                    Slog.d(TAG, "Ignoring lift event because device is awake");
                 }
+
+                mCameraLiftRegistered = sensorManager.requestTriggerSensor(mCameraLiftTriggerListener,
+                        mCameraLiftTriggerSensor);
+
+                if (DBG) Slog.d(TAG, "Camera lift trigger sensor re-registered: " + mCameraLiftRegistered);
                 return;
             }
         }
-
-        @Override
-        public void onAccuracyChanged(Sensor sensor, int accuracy) {
-            // Ignored.
-        }
     }
 }
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index a94bf79..e3ebf4d 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -244,20 +244,22 @@
 
         // get the path to the odex or oat file
         String baseCodePath = cameraInfo.getBaseCodePath();
-        String odex = null;
+        String[] files = null;
         try {
-            odex = DexFile.getDexFileOutputPath(baseCodePath, arch);
+            files = DexFile.getDexFileOutputPaths(baseCodePath, arch);
         } catch (IOException ioe) {}
-        if (odex == null) {
+        if (files == null) {
             return true;
         }
 
         //not pinning the oat/odex is not a fatal error
-        pf = pinFile(odex, 0, 0, MAX_CAMERA_PIN_SIZE);
-        if (pf != null) {
-            mPinnedCameraFiles.add(pf);
-            if (DEBUG) {
-                Slog.i(TAG, "Pinned " + pf.mFilename);
+        for (String file : files) {
+            pf = pinFile(file, 0, 0, MAX_CAMERA_PIN_SIZE);
+            if (pf != null) {
+                mPinnedCameraFiles.add(pf);
+                if (DEBUG) {
+                    Slog.i(TAG, "Pinned " + pf.mFilename);
+                }
             }
         }
 
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 452fe1d..cffb158 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -3009,6 +3009,18 @@
         }
     }
 
+    @Override
+    public void secdiscard(String path) {
+        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
+        waitForReady();
+
+        try {
+            mCryptConnector.execute("cryptfs", "secdiscard", escapeNull(path));
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
     class AppFuseMountScope extends AppFuseBridge.MountScope {
         boolean opened = false;
 
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index 10b2609..72ff606 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -164,6 +164,13 @@
         }
     }
 
+    /**
+     * @return true if system has completed the boot; false otherwise.
+     */
+    public boolean isBootCompleted() {
+        return mCurrentPhase >= SystemService.PHASE_BOOT_COMPLETED;
+    }
+
     public void startUser(final int userHandle) {
         Slog.i(TAG, "Calling onStartUser u" + userHandle);
         final int serviceLen = mServices.size();
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 5e03508..2680b425 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -780,7 +780,8 @@
                 smap.removeMessages(ServiceMap.MSG_UPDATE_FOREGROUND_APPS);
                 if (nextUpdateTime < Long.MAX_VALUE) {
                     Message msg = smap.obtainMessage();
-                    smap.sendMessageAtTime(msg, nextUpdateTime);
+                    smap.sendMessageAtTime(msg, nextUpdateTime
+                            + SystemClock.uptimeMillis() - SystemClock.elapsedRealtime());
                 }
             }
             if (!smap.mActiveForegroundAppsChanged) {
@@ -811,30 +812,35 @@
             Intent intent;
             String title;
             String msg;
+            String[] pkgs;
             if (active.size() == 1) {
                 intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                 intent.setData(Uri.fromParts("package", active.get(0).mPackageName, null));
                 title = context.getString(
                         R.string.foreground_service_app_in_background, active.get(0).mLabel);
                 msg = context.getString(R.string.foreground_service_tap_for_details);
+                pkgs = new String[] { active.get(0).mPackageName };
             } else {
                 intent = new Intent(Settings.ACTION_FOREGROUND_SERVICES_SETTINGS);
-                String[] pkgs = new String[active.size()];
+                pkgs = new String[active.size()];
                 for (int i = 0; i < active.size(); i++) {
                     pkgs[i] = active.get(i).mPackageName;
                 }
                 intent.putExtra("packages", pkgs);
                 title = context.getString(
                         R.string.foreground_service_apps_in_background, active.size());
-                msg =  active.get(0).mLabel.toString();
+                msg = active.get(0).mLabel.toString();
                 for (int i = 1; i < active.size(); i++) {
                     msg = context.getString(R.string.foreground_service_multiple_separator,
                             msg, active.get(i).mLabel);
                 }
             }
+            Bundle notificationBundle = new Bundle();
+            notificationBundle.putStringArray(Notification.EXTRA_FOREGROUND_APPS, pkgs);
             Notification.Builder n =
                     new Notification.Builder(context,
                             SystemNotificationChannels.FOREGROUND_SERVICE)
+                            .addExtras(notificationBundle)
                             .setSmallIcon(R.drawable.ic_check_circle_24px)
                             .setOngoing(true)
                             .setShowWhen(false)
@@ -854,10 +860,11 @@
         }
     }
 
-    private void requestUpdateActiveForegroundAppsLocked(ServiceMap smap, long time) {
+    private void requestUpdateActiveForegroundAppsLocked(ServiceMap smap, long timeElapsed) {
         Message msg = smap.obtainMessage(ServiceMap.MSG_UPDATE_FOREGROUND_APPS);
-        if (time != 0) {
-            smap.sendMessageAtTime(msg, time);
+        if (timeElapsed != 0) {
+            smap.sendMessageAtTime(msg,
+                    timeElapsed + SystemClock.uptimeMillis() - SystemClock.elapsedRealtime());
         } else {
             smap.mActiveForegroundAppsChanged = true;
             smap.sendMessage(msg);
@@ -909,6 +916,9 @@
                     if (changed) {
                         requestUpdateActiveForegroundAppsLocked(smap,
                                 nowElapsed + mAm.mConstants.FOREGROUND_SERVICE_UI_MIN_TIME);
+                    } else if (smap.mActiveForegroundApps.size() > 0) {
+                        // Just being paranoid.
+                        requestUpdateActiveForegroundAppsLocked(smap, 0);
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 4e00f2d..55ec3b0 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -149,6 +149,7 @@
 import android.util.Slog;
 import android.util.TimeUtils;
 import android.view.AppTransitionAnimationSpec;
+import android.view.IAppTransitionAnimationSpecsFuture;
 import android.view.IApplicationToken;
 import android.view.WindowManager.LayoutParams;
 
@@ -1437,7 +1438,13 @@
                 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
                 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
                     final AppTransitionAnimationSpec[] specs = pendingOptions.getAnimSpecs();
-                    if (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_DOWN
+                    final IAppTransitionAnimationSpecsFuture specsFuture =
+                            pendingOptions.getSpecsFuture();
+                    if (specsFuture != null) {
+                        service.mWindowManager.overridePendingAppTransitionMultiThumbFuture(
+                                specsFuture, pendingOptions.getOnAnimationStartListener(),
+                                animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP);
+                    } else if (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_DOWN
                             && specs != null) {
                         service.mWindowManager.overridePendingAppTransitionMultiThumb(
                                 specs, pendingOptions.getOnAnimationStartListener(),
@@ -2165,7 +2172,8 @@
         final boolean shown = mWindowContainerController.addStartingWindow(packageName, theme,
                 compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
                 prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
-                allowTaskSnapshot());
+                allowTaskSnapshot(),
+                state.ordinal() >= RESUMED.ordinal() && state.ordinal() <= STOPPED.ordinal());
         if (shown) {
             mStartingWindowState = STARTING_WINDOW_SHOWN;
         }
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index b5d3040..ad14ea5 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1152,11 +1152,15 @@
 
     void updateActivityApplicationInfoLocked(ApplicationInfo aInfo) {
         final String packageName = aInfo.packageName;
+        final int userId = UserHandle.getUserId(aInfo.uid);
+
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
             final List<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
-                if (packageName.equals(activities.get(activityNdx).packageName)) {
-                    activities.get(activityNdx).info.applicationInfo = aInfo;
+                final ActivityRecord ar = activities.get(activityNdx);
+
+                if ((userId == ar.userId) && packageName.equals(ar.packageName)) {
+                    ar.info.applicationInfo = aInfo;
                 }
             }
         }
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index b2f655c..9fcd593 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2998,7 +2998,8 @@
 
         stack.animateResizePinnedStack(sourceHintBounds, destBounds, -1 /* animationDuration */,
                 true /* schedulePipModeChangedOnAnimationEnd */);
-        mService.mTaskChangeNotificationController.notifyActivityPinned(r.packageName);
+        mService.mTaskChangeNotificationController.notifyActivityPinned(r.packageName,
+                r.getTask().taskId);
     }
 
     /** Move activity with its stack to front and make the stack focused. */
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index a2eec5c..960351b 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -533,11 +533,12 @@
                     auxiliaryResponse, originalIntent, resolvedType, callingPackage,
                     verificationBundle, userId);
         }
-        return InstantAppResolver.buildEphemeralInstallerIntent(originalIntent,
-            auxiliaryResponse.failureIntent, callingPackage, verificationBundle,
-            resolvedType, userId, auxiliaryResponse.packageName,
-            auxiliaryResponse.splitName, auxiliaryResponse.versionCode,
-            auxiliaryResponse.token, auxiliaryResponse.needsPhaseTwo);
+        return InstantAppResolver.buildEphemeralInstallerIntent(
+                Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE, originalIntent,
+                auxiliaryResponse.failureIntent, callingPackage, verificationBundle,
+                resolvedType, userId, auxiliaryResponse.packageName, auxiliaryResponse.splitName,
+                auxiliaryResponse.versionCode, auxiliaryResponse.token,
+                auxiliaryResponse.needsPhaseTwo);
     }
 
     void postStartActivityProcessing(
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 4db5c85..11fc40b 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -183,7 +183,6 @@
     }
 
     private native int getPlatformLowPowerStats(ByteBuffer outBuffer);
-    private native int getSubsystemLowPowerStats(ByteBuffer outBuffer);
     private CharsetDecoder mDecoderStat = StandardCharsets.UTF_8
                     .newDecoder()
                     .onMalformedInput(CodingErrorAction.REPLACE)
@@ -215,28 +214,6 @@
         }
     }
 
-    @Override
-    public String getSubsystemLowPowerStats() {
-        Slog.d(TAG, "begin getSubsystemLowPowerStats");
-        try {
-            mUtf8BufferStat.clear();
-            mUtf16BufferStat.clear();
-            mDecoderStat.reset();
-            int bytesWritten = getSubsystemLowPowerStats(mUtf8BufferStat);
-            if (bytesWritten < 0) {
-                return null;
-            } else if (bytesWritten == 0) {
-                return "Empty";
-            }
-            mUtf8BufferStat.limit(bytesWritten);
-            mDecoderStat.decode(mUtf8BufferStat, mUtf16BufferStat, true);
-            mUtf16BufferStat.flip();
-            return mUtf16BufferStat.toString();
-        } finally {
-            Slog.d(TAG, "end getSubsystemLowPowerStats");
-        }
-    }
-
     BatteryStatsService(File systemDir, Handler handler) {
         // Our handler here will be accessing the disk, use a different thread than
         // what the ActivityManagerService gave us (no I/O on that one!).
diff --git a/services/core/java/com/android/server/am/TaskChangeNotificationController.java b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
index f5d7b68..ea9ff59 100644
--- a/services/core/java/com/android/server/am/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
@@ -96,7 +96,7 @@
     };
 
     private final TaskStackConsumer mNotifyActivityPinned = (l, m) -> {
-        l.onActivityPinned((String) m.obj);
+        l.onActivityPinned((String) m.obj, m.arg1);
     };
 
     private final TaskStackConsumer mNotifyActivityUnpinned = (l, m) -> {
@@ -279,10 +279,10 @@
     }
 
     /** Notifies all listeners when an Activity is pinned. */
-    void notifyActivityPinned(String packageName) {
+    void notifyActivityPinned(String packageName, int taskId) {
         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
         final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG,
-                packageName);
+                taskId, 0, packageName);
         forAllLocalListeners(mNotifyActivityPinned, msg);
         msg.sendToTarget();
     }
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index dcd58e7..702cbbe 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -67,6 +67,10 @@
                     .createIfNeeded()
                     .build();
 
+    // like a PLAY_CREATE_IF_NEEDED operation but with a skip to the end of the ramp
+    private static final VolumeShaper.Operation PLAY_SKIP_RAMP =
+            new VolumeShaper.Operation.Builder(PLAY_CREATE_IF_NEEDED).setXOffset(1.0f).build();
+
     private final ArrayList<PlayMonitorClient> mClients = new ArrayList<PlayMonitorClient>();
     // a public client is one that needs an anonymized version of the playback configurations, we
     // keep track of whether there is at least one to know when we need to create the list of
@@ -487,17 +491,19 @@
     private static final class DuckingManager {
         private final HashMap<Integer, DuckedApp> mDuckers = new HashMap<Integer, DuckedApp>();
 
-        void duckUid(int uid, ArrayList<AudioPlaybackConfiguration> apcsToDuck) {
+        synchronized void duckUid(int uid, ArrayList<AudioPlaybackConfiguration> apcsToDuck) {
+            if (DEBUG) {  Log.v(TAG, "DuckingManager: duckUid() uid:"+ uid); }
             if (!mDuckers.containsKey(uid)) {
                 mDuckers.put(uid, new DuckedApp(uid));
             }
             final DuckedApp da = mDuckers.get(uid);
             for (AudioPlaybackConfiguration apc : apcsToDuck) {
-                da.addDuck(apc);
+                da.addDuck(apc, false /*skipRamp*/);
             }
         }
 
-        void unduckUid(int uid, HashMap<Integer, AudioPlaybackConfiguration> players) {
+        synchronized void unduckUid(int uid, HashMap<Integer, AudioPlaybackConfiguration> players) {
+            if (DEBUG) {  Log.v(TAG, "DuckingManager: unduckUid() uid:"+ uid); }
             final DuckedApp da = mDuckers.remove(uid);
             if (da == null) {
                 return;
@@ -506,25 +512,27 @@
         }
 
         // pre-condition: apc.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED
-        void checkDuck(@NonNull AudioPlaybackConfiguration apc) {
+        synchronized void checkDuck(@NonNull AudioPlaybackConfiguration apc) {
+            if (DEBUG) {  Log.v(TAG, "DuckingManager: checkDuck() player piid:"
+                    + apc.getPlayerInterfaceId()+ " uid:"+ apc.getClientUid()); }
             final DuckedApp da = mDuckers.get(apc.getClientUid());
             if (da == null) {
                 return;
             }
-            // FIXME here the player needs to be put in a state that is the same as if it
-            //   had been ducked as it starts. At the moment, this works already for linked
-            //   players, as is the case in gapless playback.
-            da.addDuck(apc);
+            da.addDuck(apc, true /*skipRamp*/);
         }
 
-        void dump(PrintWriter pw) {
+        synchronized void dump(PrintWriter pw) {
             for (DuckedApp da : mDuckers.values()) {
                 da.dump(pw);
             }
         }
 
-        void removeReleased(@NonNull AudioPlaybackConfiguration apc) {
-            final DuckedApp da = mDuckers.get(apc.getClientUid());
+        synchronized void removeReleased(@NonNull AudioPlaybackConfiguration apc) {
+            final int uid = apc.getClientUid();
+            if (DEBUG) {  Log.v(TAG, "DuckingManager: removedReleased() player piid: "
+                    + apc.getPlayerInterfaceId() + " uid:" + uid); }
+            final DuckedApp da = mDuckers.get(uid);
             if (da == null) {
                 return;
             }
@@ -550,20 +558,21 @@
             // pre-conditions:
             //  * apc != null
             //  * apc.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED
-            void addDuck(@NonNull AudioPlaybackConfiguration apc) {
+            void addDuck(@NonNull AudioPlaybackConfiguration apc, boolean skipRamp) {
                 final int piid = new Integer(apc.getPlayerInterfaceId());
                 if (mDuckedPlayers.contains(piid)) {
-                    if (DEBUG) { Log.v(TAG, "player " + piid + " already ducked"); }
+                    if (DEBUG) { Log.v(TAG, "player piid:" + piid + " already ducked"); }
                     return;
                 }
                 try {
-                    Log.v(TAG, "ducking player " + apc.getPlayerInterfaceId() + " uid:" + mUid);
+                    Log.v(TAG, "ducking (skipRamp=" + skipRamp + ") player piid:"
+                            + apc.getPlayerInterfaceId() + " uid:" + mUid);
                     apc.getPlayerProxy().applyVolumeShaper(
                             DUCK_VSHAPE,
-                            PLAY_CREATE_IF_NEEDED);
+                            skipRamp ? PLAY_SKIP_RAMP : PLAY_CREATE_IF_NEEDED);
                     mDuckedPlayers.add(piid);
                 } catch (Exception e) {
-                    Log.e(TAG, "Error ducking player " + piid + " uid:" + mUid, e);
+                    Log.e(TAG, "Error ducking player piid:" + piid + " uid:" + mUid, e);
                 }
             }
 
@@ -577,13 +586,13 @@
                                     DUCK_ID,
                                     VolumeShaper.Operation.REVERSE);
                         } catch (Exception e) {
-                            Log.e(TAG, "Error unducking player " + piid + " uid:" + mUid, e);
+                            Log.e(TAG, "Error unducking player piid:" + piid + " uid:" + mUid, e);
                         }
                     } else {
                         // this piid was in the list of ducked players, but wasn't found
                         if (DEBUG) {
-                            Log.v(TAG, "Error unducking player " + piid + ", player not found for"
-                                    + " uid " + mUid);
+                            Log.v(TAG, "Error unducking player piid:" + piid
+                                    + ", player not found for uid " + mUid);
                         }
                     }
                 }
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index 3677905..0ee2a41 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -971,14 +971,18 @@
                 return result;
             }
         }
-        // Otherwise wait until https probe completes and use its result.
+        // Otherwise wait until http and https probes completes and use their results.
         try {
+            httpProbe.join();
+            if (httpProbe.result().isPortal()) {
+                return httpProbe.result();
+            }
             httpsProbe.join();
+            return httpsProbe.result();
         } catch (InterruptedException e) {
-            validationLog("Error: https probe wait interrupted!");
+            validationLog("Error: http or https probe wait interrupted!");
             return CaptivePortalProbeResult.FAILED;
         }
-        return httpsProbe.result();
     }
 
     private URL makeURL(String url) {
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 925dfb5..6e8e939 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -20,6 +20,7 @@
 import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
+import static com.android.server.ConnectivityService.SHORT_ARG;
 
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -47,6 +48,7 @@
 import android.net.NetworkState;
 import android.net.NetworkUtils;
 import android.net.RouteInfo;
+import android.net.util.SharedLog;
 import android.net.wifi.WifiManager;
 import android.os.Binder;
 import android.os.Bundle;
@@ -62,7 +64,6 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArrayMap;
-import android.util.LocalLog;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -84,6 +85,7 @@
 import com.android.server.connectivity.tethering.SimChangeListener;
 import com.android.server.connectivity.tethering.TetherInterfaceStateMachine;
 import com.android.server.connectivity.tethering.TetheringConfiguration;
+import com.android.server.connectivity.tethering.TetheringDependencies;
 import com.android.server.connectivity.tethering.UpstreamNetworkMonitor;
 import com.android.server.net.BaseNetworkObserver;
 
@@ -148,9 +150,7 @@
         }
     }
 
-    private final static int MAX_LOG_RECORDS = 500;
-
-    private final LocalLog mLocalLog = new LocalLog(MAX_LOG_RECORDS);
+    private final SharedLog mLog = new SharedLog(TAG);
 
     // used to synchronize public access to members
     private final Object mPublicSync;
@@ -181,8 +181,9 @@
 
     public Tethering(Context context, INetworkManagementService nmService,
             INetworkStatsService statsService, INetworkPolicyManager policyManager,
-            Looper looper, MockableSystemProperties systemProperties) {
-        mLocalLog.log("CONSTRUCTED");
+            Looper looper, MockableSystemProperties systemProperties,
+            TetheringDependencies deps) {
+        mLog.mark("constructed");
         mContext = context;
         mNMService = nmService;
         mStatsService = statsService;
@@ -197,9 +198,10 @@
         mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper);
         mTetherMasterSM.start();
 
-        mOffloadController = new OffloadController(mTetherMasterSM.getHandler());
+        mOffloadController = new OffloadController(mTetherMasterSM.getHandler(),
+                deps.getOffloadHardwareInterface(), mLog);
         mUpstreamNetworkMonitor = new UpstreamNetworkMonitor(
-                mContext, mTetherMasterSM, TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
+                mContext, mTetherMasterSM, TetherMasterSM.EVENT_UPSTREAM_CALLBACK, mLog);
         mForwardedDownstreams = new HashSet<>();
         mSimChange = new SimChangeListener(
                 mContext, mTetherMasterSM.getHandler(), () -> reevaluateSimCardProvisioning());
@@ -770,7 +772,7 @@
         mLastNotificationId = id;
 
         notificationManager.notifyAsUser(null, mLastNotificationId,
-                mTetheredNotificationBuilder.build(), UserHandle.ALL);
+                mTetheredNotificationBuilder.buildInto(new Notification()), UserHandle.ALL);
     }
 
     private void clearTetheredNotification() {
@@ -1145,7 +1147,7 @@
             addState(mSetDnsForwardersErrorState);
 
             mNotifyList = new ArrayList<>();
-            mIPv6TetheringCoordinator = new IPv6TetheringCoordinator(mNotifyList);
+            mIPv6TetheringCoordinator = new IPv6TetheringCoordinator(mNotifyList, mLog);
             setInitialState(mInitialState);
         }
 
@@ -1192,7 +1194,7 @@
                 try {
                     mNMService.setIpForwardingEnabled(true);
                 } catch (Exception e) {
-                    mLocalLog.log("ERROR " + e);
+                    mLog.e(e);
                     transitionTo(mSetIpForwardingEnabledErrorState);
                     return false;
                 }
@@ -1205,12 +1207,12 @@
                         mNMService.stopTethering();
                         mNMService.startTethering(cfg.dhcpRanges);
                     } catch (Exception ee) {
-                        mLocalLog.log("ERROR " + ee);
+                        mLog.e(ee);
                         transitionTo(mStartTetheringErrorState);
                         return false;
                     }
                 }
-                mLocalLog.log("SET master tether settings: ON");
+                mLog.log("SET master tether settings: ON");
                 return true;
             }
 
@@ -1218,19 +1220,19 @@
                 try {
                     mNMService.stopTethering();
                 } catch (Exception e) {
-                    mLocalLog.log("ERROR " + e);
+                    mLog.e(e);
                     transitionTo(mStopTetheringErrorState);
                     return false;
                 }
                 try {
                     mNMService.setIpForwardingEnabled(false);
                 } catch (Exception e) {
-                    mLocalLog.log("ERROR " + e);
+                    mLog.e(e);
                     transitionTo(mSetIpForwardingDisabledErrorState);
                     return false;
                 }
                 transitionTo(mInitialState);
-                mLocalLog.log("SET master tether settings: OFF");
+                mLog.log("SET master tether settings: OFF");
                 return true;
             }
 
@@ -1356,13 +1358,13 @@
                 }
                 try {
                     mNMService.setDnsForwarders(network, dnsServers);
-                    mLocalLog.log(String.format(
-                            "SET DNS forwarders: network=%s dnsServers=[%s]",
+                    mLog.log(String.format(
+                            "SET DNS forwarders: network=%s dnsServers=%s",
                             network, Arrays.toString(dnsServers)));
                 } catch (Exception e) {
                     // TODO: Investigate how this can fail and what exactly
                     // happens if/when such failures occur.
-                    mLocalLog.log("ERROR setting DNS forwarders failed, " + e);
+                    mLog.e("setting DNS forwarders failed, " + e);
                     transitionTo(mSetDnsForwardersErrorState);
                 }
             }
@@ -1491,7 +1493,8 @@
                         handleInterfaceServingStateInactive(who);
 
                         if (mNotifyList.isEmpty()) {
-                            // transitions appropriately
+                            // This transitions us out of TetherModeAliveState,
+                            // either to InitialState or an error state.
                             turnOffMasterTetherSettings();
                             break;
                         }
@@ -1717,12 +1720,23 @@
 
         pw.println("Log:");
         pw.increaseIndent();
-        mLocalLog.readOnlyLocalLog().dump(fd, pw, args);
+        if (argsContain(args, SHORT_ARG)) {
+            pw.println("<log removed for brevity>");
+        } else {
+            mLog.dump(fd, pw, args);
+        }
         pw.decreaseIndent();
 
         pw.decreaseIndent();
     }
 
+    private static boolean argsContain(String[] args, String target) {
+        for (String arg : args) {
+            if (arg.equals(target)) return true;
+        }
+        return false;
+    }
+
     @Override
     public void notifyInterfaceStateChange(String iface, TetherInterfaceStateMachine who,
                                            int state, int error) {
@@ -1736,8 +1750,7 @@
             }
         }
 
-        mLocalLog.log(String.format("OBSERVED iface=%s state=%s error=%s",
-                iface, state, error));
+        mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, error));
 
         try {
             // Notify that we're tethering (or not) this interface.
@@ -1775,8 +1788,8 @@
     private void trackNewTetherableInterface(String iface, int interfaceType) {
         TetherState tetherState;
         tetherState = new TetherState(new TetherInterfaceStateMachine(iface, mLooper,
-                interfaceType, mNMService, mStatsService, this,
-                new IPv6TetheringInterfaceServices(iface, mNMService)));
+                interfaceType, mLog, mNMService, mStatsService, this,
+                new IPv6TetheringInterfaceServices(iface, mNMService, mLog)));
         mTetherStates.put(iface, tetherState);
         tetherState.stateMachine.start();
     }
diff --git a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java
index 2485654..518f6c1 100644
--- a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java
+++ b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java
@@ -25,6 +25,7 @@
 import android.net.NetworkState;
 import android.net.RouteInfo;
 import android.net.util.NetworkConstants;
+import android.net.util.SharedLog;
 import android.util.Log;
 
 import java.net.Inet6Address;
@@ -64,6 +65,7 @@
     }
 
     private final ArrayList<TetherInterfaceStateMachine> mNotifyList;
+    private final SharedLog mLog;
     // NOTE: mActiveDownstreams is a list and not a hash data structure because
     // we keep active downstreams in arrival order.  This is done so /64s can
     // be parceled out on a "first come, first served" basis and a /64 used by
@@ -74,8 +76,10 @@
     private short mNextSubnetId;
     private NetworkState mUpstreamNetworkState;
 
-    public IPv6TetheringCoordinator(ArrayList<TetherInterfaceStateMachine> notifyList) {
+    public IPv6TetheringCoordinator(ArrayList<TetherInterfaceStateMachine> notifyList,
+                                    SharedLog log) {
         mNotifyList = notifyList;
+        mLog = log.forSubComponent(TAG);
         mActiveDownstreams = new LinkedList<>();
         mUniqueLocalPrefix = generateUniqueLocalPrefix();
         mNextSubnetId = 0;
@@ -115,7 +119,7 @@
         if (VDBG) {
             Log.d(TAG, "updateUpstreamNetworkState: " + toDebugString(ns));
         }
-        if (!canTetherIPv6(ns)) {
+        if (!canTetherIPv6(ns, mLog)) {
             stopIPv6TetheringOnAllInterfaces();
             setUpstreamNetworkState(null);
             return;
@@ -150,9 +154,7 @@
                     null);
         }
 
-        if (DBG) {
-            Log.d(TAG, "setUpstreamNetworkState: " + toDebugString(mUpstreamNetworkState));
-        }
+        mLog.log("setUpstreamNetworkState: " + toDebugString(mUpstreamNetworkState));
     }
 
     private void updateIPv6TetheringInterfaces() {
@@ -206,7 +208,7 @@
         return null;
     }
 
-    private static boolean canTetherIPv6(NetworkState ns) {
+    private static boolean canTetherIPv6(NetworkState ns, SharedLog sharedLog) {
         // Broadly speaking:
         //
         //     [1] does the upstream have an IPv6 default route?
@@ -260,13 +262,11 @@
 
         final boolean outcome = canTether && supportedConfiguration;
 
-        if (VDBG) {
-            if (ns == null) {
-                Log.d(TAG, "No available upstream.");
-            } else {
-                Log.d(TAG, String.format("IPv6 tethering is %s for upstream: %s",
-                        (outcome ? "available" : "not available"), toDebugString(ns)));
-            }
+        if (ns == null) {
+            sharedLog.log("No available upstream.");
+        } else {
+            sharedLog.log(String.format("IPv6 tethering is %s for upstream: %s",
+                    (outcome ? "available" : "not available"), toDebugString(ns)));
         }
 
         return outcome;
diff --git a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java
index c6a7925..adf4af8 100644
--- a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java
+++ b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java
@@ -28,10 +28,10 @@
 import android.net.ip.RouterAdvertisementDaemon;
 import android.net.ip.RouterAdvertisementDaemon.RaParams;
 import android.net.util.NetdService;
+import android.net.util.SharedLog;
 import android.os.INetworkManagementService;
 import android.os.ServiceSpecificException;
 import android.os.RemoteException;
-import android.util.Log;
 import android.util.Slog;
 
 import java.net.Inet6Address;
@@ -54,6 +54,7 @@
 
     private final String mIfName;
     private final INetworkManagementService mNMService;
+    private final SharedLog mLog;
 
     private NetworkInterface mNetworkInterface;
     private byte[] mHwAddr;
@@ -61,9 +62,11 @@
     private RouterAdvertisementDaemon mRaDaemon;
     private RaParams mLastRaParams;
 
-    public IPv6TetheringInterfaceServices(String ifname, INetworkManagementService nms) {
+    public IPv6TetheringInterfaceServices(
+            String ifname, INetworkManagementService nms, SharedLog log) {
         mIfName = ifname;
         mNMService = nms;
+        mLog = log.forSubComponent(mIfName);
     }
 
     public boolean start() {
@@ -72,12 +75,12 @@
         try {
             mNetworkInterface = NetworkInterface.getByName(mIfName);
         } catch (SocketException e) {
-            Log.e(TAG, "Error looking up NetworkInterfaces for " + mIfName, e);
+            mLog.e("Error looking up NetworkInterfaces: " + e);
             stop();
             return false;
         }
         if (mNetworkInterface == null) {
-            Log.e(TAG, "Failed to find NetworkInterface for " + mIfName);
+            mLog.e("Failed to find NetworkInterface");
             stop();
             return false;
         }
@@ -85,7 +88,7 @@
         try {
             mHwAddr = mNetworkInterface.getHardwareAddress();
         } catch (SocketException e) {
-            Log.e(TAG, "Failed to find hardware address for " + mIfName, e);
+            mLog.e("Failed to find hardware address: " + e);
             stop();
             return false;
         }
@@ -161,11 +164,11 @@
             try {
                 final int removalFailures = mNMService.removeRoutesFromLocalNetwork(toBeRemoved);
                 if (removalFailures > 0) {
-                    Log.e(TAG, String.format("Failed to remove %d IPv6 routes from local table.",
+                    mLog.e(String.format("Failed to remove %d IPv6 routes from local table.",
                             removalFailures));
                 }
             } catch (RemoteException e) {
-                Log.e(TAG, "Failed to remove IPv6 routes from local table: ", e);
+                mLog.e("Failed to remove IPv6 routes from local table: " + e);
             }
         }
 
@@ -195,7 +198,7 @@
                     // error (EEXIST is silently ignored).
                     mNMService.addInterfaceToLocalNetwork(mIfName, toBeAdded);
                 } catch (RemoteException e) {
-                    Log.e(TAG, "Failed to add IPv6 routes to local table: ", e);
+                    mLog.e("Failed to add IPv6 routes to local table: " + e);
                 }
             }
         }
@@ -206,7 +209,7 @@
         final INetd netd = NetdService.getInstance();
         if (netd == null) {
             if (newDnses != null) newDnses.clear();
-            Log.e(TAG, "No netd service instance available; not setting local IPv6 addresses");
+            mLog.e("No netd service instance available; not setting local IPv6 addresses");
             return;
         }
 
@@ -217,7 +220,7 @@
                 try {
                     netd.interfaceDelAddress(mIfName, dnsString, RFC7421_PREFIX_LENGTH);
                 } catch (ServiceSpecificException | RemoteException e) {
-                    Log.e(TAG, "Failed to remove local dns IP: " + dnsString, e);
+                    mLog.e("Failed to remove local dns IP " + dnsString + ": " + e);
                 }
             }
         }
@@ -234,7 +237,7 @@
                 try {
                     netd.interfaceAddAddress(mIfName, dnsString, RFC7421_PREFIX_LENGTH);
                 } catch (ServiceSpecificException | RemoteException e) {
-                    Log.e(TAG, "Failed to add local dns IP: " + dnsString, e);
+                    mLog.e("Failed to add local dns IP " + dnsString + ": " + e);
                     newDnses.remove(dns);
                 }
             }
@@ -243,7 +246,7 @@
         try {
             netd.tetherApplyDnsInterfaces();
         } catch (ServiceSpecificException | RemoteException e) {
-            Log.e(TAG, "Failed to update local DNS caching server");
+            mLog.e("Failed to update local DNS caching server");
             if (newDnses != null) newDnses.clear();
         }
     }
diff --git a/services/core/java/com/android/server/connectivity/tethering/OffloadController.java b/services/core/java/com/android/server/connectivity/tethering/OffloadController.java
index 220e751..ec7ab5b 100644
--- a/services/core/java/com/android/server/connectivity/tethering/OffloadController.java
+++ b/services/core/java/com/android/server/connectivity/tethering/OffloadController.java
@@ -18,10 +18,11 @@
 
 import android.net.LinkProperties;
 import android.os.Handler;
-import android.util.Log;
+import android.net.util.SharedLog;
 
 /**
- * A wrapper around hardware offload interface.
+ * A class to encapsulate the business logic of programming the tethering
+ * hardware offload interface.
  *
  * @hide
  */
@@ -29,25 +30,50 @@
     private static final String TAG = OffloadController.class.getSimpleName();
 
     private final Handler mHandler;
+    private final OffloadHardwareInterface mHwInterface;
+    private final SharedLog mLog;
+    private boolean mConfigInitialized;
+    private boolean mControlInitialized;
     private LinkProperties mUpstreamLinkProperties;
 
-    public OffloadController(Handler h) {
+    public OffloadController(Handler h, OffloadHardwareInterface hwi, SharedLog log) {
         mHandler = h;
+        mHwInterface = hwi;
+        mLog = log.forSubComponent(TAG);
     }
 
     public void start() {
-        // TODO: initOffload() and configure callbacks to be handled on our
-        // preferred Handler.
-        Log.d(TAG, "tethering offload not supported");
+        if (started()) return;
+
+        if (!mConfigInitialized) {
+            mConfigInitialized = mHwInterface.initOffloadConfig();
+            if (!mConfigInitialized) {
+                mLog.i("tethering offload config not supported");
+                return;
+            }
+        }
+
+        // TODO: Create and register ITetheringOffloadCallback.
+        mControlInitialized = mHwInterface.initOffloadControl();
     }
 
     public void stop() {
-        // TODO: stopOffload().
         mUpstreamLinkProperties = null;
+        mHwInterface.stopOffloadControl();
+        mControlInitialized = false;
+        mConfigInitialized = false;
     }
 
     public void setUpstreamLinkProperties(LinkProperties lp) {
+        if (!started()) return;
+
         // TODO: setUpstreamParameters().
         mUpstreamLinkProperties = lp;
     }
+
+    // TODO: public void addDownStream(...)
+
+    private boolean started() {
+        return mConfigInitialized && mControlInitialized;
+    }
 }
diff --git a/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java b/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java
new file mode 100644
index 0000000..87fc491
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.server.connectivity.tethering;
+
+import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
+import android.hardware.tetheroffload.control.V1_0.IOffloadControl.stopOffloadCallback;
+import android.os.RemoteException;
+import android.util.Log;
+
+
+/**
+ * Capture tethering dependencies, for injection.
+ *
+ * @hide
+ */
+public class OffloadHardwareInterface {
+    private static final String TAG = OffloadHardwareInterface.class.getSimpleName();
+
+    private static native boolean configOffload();
+
+    private IOffloadControl mOffloadControl;
+
+    public OffloadHardwareInterface() {}
+
+    public boolean initOffloadConfig() {
+        return configOffload();
+    }
+
+    // TODO: Extend this to take a TetheringControlCallback for registration.
+    public boolean initOffloadControl() {
+        if (mOffloadControl == null) {
+            try {
+                mOffloadControl = IOffloadControl.getService();
+            } catch (RemoteException e) {
+                Log.d(TAG, "tethering offload control not supported: " + e);
+                return false;
+            }
+        }
+
+        // TODO: call mOffloadControl.initOffload(...callback...);
+
+        return true;
+    }
+
+    public void stopOffloadControl() {
+        if (mOffloadControl == null) return;
+
+        try {
+            final stopOffloadCallback cb = new stopOffloadCallback() {
+                @Override
+                public void onValues(boolean success, String errMsg) {
+                    if (success) return;
+
+                    Log.e(TAG, "stopOffload failed: " + errMsg);
+                }
+            };
+            mOffloadControl.stopOffload(cb);
+        } catch (RemoteException e) {
+            Log.d(TAG, "failed to stopOffload: " + e);
+        }
+        mOffloadControl = null;
+    }
+}
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
index d3cfd87..4a1d405 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
@@ -22,6 +22,7 @@
 import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.NetworkUtils;
+import android.net.util.SharedLog;
 import android.os.INetworkManagementService;
 import android.os.Looper;
 import android.os.Message;
@@ -82,6 +83,7 @@
     private final State mTetheredState;
     private final State mUnavailableState;
 
+    private final SharedLog mLog;
     private final INetworkManagementService mNMService;
     private final INetworkStatsService mStatsService;
     private final IControlsTethering mTetherController;
@@ -93,10 +95,12 @@
     private int mLastError;
     private String mMyUpstreamIfaceName;  // may change over time
 
-    public TetherInterfaceStateMachine(String ifaceName, Looper looper, int interfaceType,
-                    INetworkManagementService nMService, INetworkStatsService statsService,
-                    IControlsTethering tetherController, IPv6TetheringInterfaceServices ipv6Svc) {
+    public TetherInterfaceStateMachine(
+            String ifaceName, Looper looper, int interfaceType, SharedLog log,
+            INetworkManagementService nMService, INetworkStatsService statsService,
+            IControlsTethering tetherController, IPv6TetheringInterfaceServices ipv6Svc) {
         super(ifaceName, looper);
+        mLog = log.forSubComponent(ifaceName);
         mNMService = nMService;
         mStatsService = statsService;
         mTetherController = tetherController;
@@ -162,7 +166,7 @@
                 mNMService.setInterfaceConfig(mIfaceName, ifcg);
             }
         } catch (Exception e) {
-            Log.e(TAG, "Error configuring interface " + mIfaceName, e);
+            mLog.e("Error configuring interface " + e);
             return false;
         }
 
@@ -203,7 +207,7 @@
                             transitionTo(mTetheredState);
                             break;
                         default:
-                            Log.e(TAG, "Invalid tethering interface serving state specified.");
+                            mLog.e("Invalid tethering interface serving state specified.");
                     }
                     break;
                 case CMD_INTERFACE_DOWN:
@@ -232,13 +236,13 @@
             try {
                 mNMService.tetherInterface(mIfaceName);
             } catch (Exception e) {
-                Log.e(TAG, "Error Tethering: " + e.toString());
+                mLog.e("Error Tethering: " + e);
                 mLastError = ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR;
                 return;
             }
 
             if (!mIPv6TetherSvc.start()) {
-                Log.e(TAG, "Failed to start IPv6TetheringInterfaceServices");
+                mLog.e("Failed to start IPv6TetheringInterfaceServices");
                 // TODO: Make this a fatal error once Bluetooth IPv6 is sorted.
                 return;
             }
@@ -255,7 +259,7 @@
                 mNMService.untetherInterface(mIfaceName);
             } catch (Exception e) {
                 mLastError = ConnectivityManager.TETHER_ERROR_UNTETHER_IFACE_ERROR;
-                Log.e(TAG, "Failed to untether interface: " + e.toString());
+                mLog.e("Failed to untether interface: " + e);
             }
 
             configureIfaceIp(false);
@@ -316,7 +320,7 @@
             maybeLogMessage(this, message.what);
             switch (message.what) {
                 case CMD_TETHER_REQUESTED:
-                    Log.e(TAG, "CMD_TETHER_REQUESTED while in local hotspot mode.");
+                    mLog.e("CMD_TETHER_REQUESTED while in local-only hotspot mode.");
                     break;
                 case CMD_TETHER_CONNECTION_CHANGED:
                     // Ignored in local hotspot state.
@@ -389,7 +393,7 @@
             boolean retValue = true;
             switch (message.what) {
                 case CMD_TETHER_REQUESTED:
-                    Log.e(TAG, "CMD_TETHER_REQUESTED while already tethering.");
+                    mLog.e("CMD_TETHER_REQUESTED while already tethering.");
                     break;
                 case CMD_TETHER_CONNECTION_CHANGED:
                     String newUpstreamIfaceName = (String)(message.obj);
@@ -406,7 +410,7 @@
                             mNMService.startInterfaceForwarding(mIfaceName,
                                     newUpstreamIfaceName);
                         } catch (Exception e) {
-                            Log.e(TAG, "Exception enabling Nat: " + e.toString());
+                            mLog.e("Exception enabling NAT: " + e);
                             cleanupUpstreamInterface(newUpstreamIfaceName);
                             mLastError = ConnectivityManager.TETHER_ERROR_ENABLE_NAT_ERROR;
                             transitionTo(mInitialState);
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java
new file mode 100644
index 0000000..be2cf08
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.server.connectivity.tethering;
+
+
+/**
+ * Capture tethering dependencies, for injection.
+ *
+ * @hide
+ */
+public class TetheringDependencies {
+    public OffloadHardwareInterface getOffloadHardwareInterface() {
+        return new OffloadHardwareInterface();
+    }
+}
diff --git a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
index 97a2d5e..be71490 100644
--- a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
@@ -29,6 +29,7 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
 import android.net.NetworkState;
+import android.net.util.SharedLog;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -73,6 +74,7 @@
     private static final int CALLBACK_MOBILE_REQUEST = 3;
 
     private final Context mContext;
+    private final SharedLog mLog;
     private final StateMachine mTarget;
     private final Handler mHandler;
     private final int mWhat;
@@ -84,16 +86,18 @@
     private boolean mDunRequired;
     private Network mCurrentDefault;
 
-    public UpstreamNetworkMonitor(Context ctx, StateMachine tgt, int what) {
+    public UpstreamNetworkMonitor(Context ctx, StateMachine tgt, int what, SharedLog log) {
         mContext = ctx;
         mTarget = tgt;
         mHandler = mTarget.getHandler();
         mWhat = what;
+        mLog = log.forSubComponent(TAG);
     }
 
     @VisibleForTesting
-    public UpstreamNetworkMonitor(StateMachine tgt, int what, ConnectivityManager cm) {
-        this(null, tgt, what);
+    public UpstreamNetworkMonitor(
+            StateMachine tgt, int what, ConnectivityManager cm, SharedLog log) {
+        this(null, tgt, what, log);
         mCM = cm;
     }
 
@@ -136,7 +140,7 @@
 
     public void registerMobileNetworkRequest() {
         if (mMobileNetworkCallback != null) {
-            Log.e(TAG, "registerMobileNetworkRequest() already registered");
+            mLog.e("registerMobileNetworkRequest() already registered");
             return;
         }
 
@@ -156,7 +160,7 @@
         // TODO: Change the timeout from 0 (no onUnavailable callback) to some
         // moderate callback timeout. This might be useful for updating some UI.
         // Additionally, we log a message to aid in any subsequent debugging.
-        Log.d(TAG, "requesting mobile upstream network: " + mobileUpstreamRequest);
+        mLog.i("requesting mobile upstream network: " + mobileUpstreamRequest);
 
         cm().requestNetwork(mobileUpstreamRequest, mMobileNetworkCallback, 0, legacyType, mHandler);
     }
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 0ef0561..9dc317a 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -71,6 +71,7 @@
 final class DisplayPowerController implements AutomaticBrightnessController.Callbacks {
     private static final String TAG = "DisplayPowerController";
     private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked";
+    private static final String SCREEN_OFF_BLOCKED_TRACE_NAME = "Screen off blocked";
 
     private static final boolean DEBUG = false;
     private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
@@ -90,6 +91,7 @@
     private static final int MSG_UPDATE_POWER_STATE = 1;
     private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
     private static final int MSG_SCREEN_ON_UNBLOCKED = 3;
+    private static final int MSG_SCREEN_OFF_UNBLOCKED = 4;
 
     private static final int PROXIMITY_UNKNOWN = -1;
     private static final int PROXIMITY_NEGATIVE = 0;
@@ -105,6 +107,7 @@
     private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0;
     private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1;
     private static final int REPORTED_TO_POLICY_SCREEN_ON = 2;
+    private static final int REPORTED_TO_POLICY_SCREEN_TURNING_OFF = 3;
 
     private final Object mLock = new Object();
 
@@ -219,6 +222,7 @@
     // The currently active screen on unblocker.  This field is non-null whenever
     // we are waiting for a callback to release it and unblock the screen.
     private ScreenOnUnblocker mPendingScreenOnUnblocker;
+    private ScreenOffUnblocker mPendingScreenOffUnblocker;
 
     // True if we were in the process of turning off the screen.
     // This allows us to recover more gracefully from situations where we abort
@@ -230,6 +234,7 @@
 
     // The elapsed real time when the screen on was blocked.
     private long mScreenOnBlockStartRealTime;
+    private long mScreenOffBlockStartRealTime;
 
     // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_SCREEN_* fields.
     private int mReportedScreenStateToPolicy;
@@ -810,9 +815,43 @@
         }
     }
 
+    private void blockScreenOff() {
+        if (mPendingScreenOffUnblocker == null) {
+            Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
+            mPendingScreenOffUnblocker = new ScreenOffUnblocker();
+            mScreenOffBlockStartRealTime = SystemClock.elapsedRealtime();
+            Slog.i(TAG, "Blocking screen off");
+        }
+    }
+
+    private void unblockScreenOff() {
+        if (mPendingScreenOffUnblocker != null) {
+            mPendingScreenOffUnblocker = null;
+            long delay = SystemClock.elapsedRealtime() - mScreenOffBlockStartRealTime;
+            Slog.i(TAG, "Unblocked screen off after " + delay + " ms");
+            Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_OFF_BLOCKED_TRACE_NAME, 0);
+        }
+    }
+
     private boolean setScreenState(int state) {
+        final boolean isOff = (state == Display.STATE_OFF);
         if (mPowerState.getScreenState() != state) {
-            final boolean wasOn = (mPowerState.getScreenState() != Display.STATE_OFF);
+
+            // If we are trying to turn screen off, give policy a chance to do something before we
+            // actually turn the screen off.
+            if (isOff && !mScreenOffBecauseOfProximity) {
+                if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON) {
+                    mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_OFF;
+                    blockScreenOff();
+                    mWindowManagerPolicy.screenTurningOff(mPendingScreenOffUnblocker);
+                    return false;
+                } else if (mPendingScreenOffUnblocker != null) {
+
+                    // Abort doing the state change until screen off is unblocked.
+                    return false;
+                }
+            }
+
             mPowerState.setScreenState(state);
 
             // Tell battery stats about the transition.
@@ -829,13 +868,21 @@
         // This surface is essentially the final state of the color fade animation and
         // it is only removed once the window manager tells us that the activity has
         // finished drawing underneath.
-        final boolean isOff = (state == Display.STATE_OFF);
         if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
                 && !mScreenOffBecauseOfProximity) {
             mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF;
             unblockScreenOn();
             mWindowManagerPolicy.screenTurnedOff();
-        } else if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
+        } else if (!isOff
+                && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) {
+
+            // We told policy already that screen was turning off, but now we changed our minds.
+            // Complete the full state transition on -> turningOff -> off.
+            unblockScreenOff();
+            mWindowManagerPolicy.screenTurnedOff();
+            mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF;
+        }
+        if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
             mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_ON;
             if (mPowerState.getColorFadeLevel() == 0.0f) {
                 blockScreenOn();
@@ -1282,6 +1329,12 @@
                         updatePowerState();
                     }
                     break;
+                case MSG_SCREEN_OFF_UNBLOCKED:
+                    if (mPendingScreenOffUnblocker == msg.obj) {
+                        unblockScreenOff();
+                        updatePowerState();
+                    }
+                    break;
             }
         }
     }
@@ -1311,4 +1364,14 @@
             mHandler.sendMessage(msg);
         }
     }
+
+    private final class ScreenOffUnblocker implements WindowManagerPolicy.ScreenOffListener {
+
+        @Override
+        public void onScreenOff() {
+            Message msg = mHandler.obtainMessage(MSG_SCREEN_OFF_UNBLOCKED, this);
+            msg.setAsynchronous(true);
+            mHandler.sendMessage(msg);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/fingerprint/RemovalClient.java b/services/core/java/com/android/server/fingerprint/RemovalClient.java
index 88a6bdd..8646107 100644
--- a/services/core/java/com/android/server/fingerprint/RemovalClient.java
+++ b/services/core/java/com/android/server/fingerprint/RemovalClient.java
@@ -85,7 +85,6 @@
         IFingerprintServiceReceiver receiver = getReceiver();
         try {
             if (receiver != null) {
-                // TODO: plumb remaining
                 receiver.onRemoved(getHalDeviceId(), fingerId, groupId, remaining);
             }
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index c08f866..b0d76e8 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -63,6 +63,7 @@
 import android.os.ShellCallback;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.os.UserManagerInternal;
 import android.provider.Settings;
 import android.util.KeyValueListParser;
 import android.util.Slog;
@@ -751,6 +752,13 @@
         }
     }
 
+    private void cancelJobsForNonExistentUsers() {
+        UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
+        synchronized (mLock) {
+            mJobs.removeJobsOfNonUsers(umi.getUserIds());
+        }
+    }
+
     void cancelJobsForPackageAndUid(String pkgName, int uid) {
         synchronized (mLock) {
             final List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid);
@@ -941,6 +949,8 @@
             } catch (RemoteException e) {
                 // ignored; both services live in system_server
             }
+            // Remove any jobs that are not associated with any of the current users.
+            cancelJobsForNonExistentUsers();
         } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
             synchronized (mLock) {
                 // Let's go!
@@ -1270,6 +1280,17 @@
         }
     }
 
+    private void stopNonReadyActiveJobsLocked() {
+        for (int i=0; i<mActiveServices.size(); i++) {
+            JobServiceContext serviceContext = mActiveServices.get(i);
+            final JobStatus running = serviceContext.getRunningJobLocked();
+            if (running != null && !running.isReady()) {
+                serviceContext.cancelExecutingJobLocked(
+                        JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED);
+            }
+        }
+    }
+
     /**
      * Run through list of jobs and execute all possible - at least one is expired so we do
      * as many as we can.
@@ -1280,6 +1301,7 @@
         }
         noteJobsNonpending(mPendingJobs);
         mPendingJobs.clear();
+        stopNonReadyActiveJobsLocked();
         mJobs.forEachJob(mReadyQueueFunctor);
         mReadyQueueFunctor.postProcess();
 
@@ -1306,9 +1328,6 @@
                     newReadyJobs = new ArrayList<JobStatus>();
                 }
                 newReadyJobs.add(job);
-            } else if (areJobConstraintsNotSatisfiedLocked(job)) {
-                stopJobOnServiceContextLocked(job,
-                        JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED);
             }
         }
 
@@ -1387,9 +1406,6 @@
                     runnableJobs = new ArrayList<>();
                 }
                 runnableJobs.add(job);
-            } else if (areJobConstraintsNotSatisfiedLocked(job)) {
-                stopJobOnServiceContextLocked(job,
-                        JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED);
             }
         }
 
@@ -1439,6 +1455,7 @@
 
         noteJobsNonpending(mPendingJobs);
         mPendingJobs.clear();
+        stopNonReadyActiveJobsLocked();
         mJobs.forEachJob(mMaybeQueueFunctor);
         mMaybeQueueFunctor.postProcess();
     }
@@ -1516,15 +1533,6 @@
     }
 
     /**
-     * Criteria for cancelling an active job:
-     *      - It's not ready
-     *      - It's running on a JSC.
-     */
-    private boolean areJobConstraintsNotSatisfiedLocked(JobStatus job) {
-        return !job.isReady() && isCurrentlyActiveLocked(job);
-    }
-
-    /**
      * Reconcile jobs in the pending queue against available execution contexts.
      * A controller can force a job into the pending queue even if it's already running, but
      * here is where we decide whether to actually execute it.
@@ -2088,6 +2096,83 @@
         }
     }
 
+    int getJobState(PrintWriter pw, String pkgName, int userId, int jobId) {
+        try {
+            final int uid = AppGlobals.getPackageManager().getPackageUid(pkgName, 0,
+                    userId != UserHandle.USER_ALL ? userId : UserHandle.USER_SYSTEM);
+            if (uid < 0) {
+                pw.print("unknown("); pw.print(pkgName); pw.println(")");
+                return JobSchedulerShellCommand.CMD_ERR_NO_PACKAGE;
+            }
+
+            synchronized (mLock) {
+                final JobStatus js = mJobs.getJobByUidAndJobId(uid, jobId);
+                if (DEBUG) Slog.d(TAG, "get-job-state " + uid + "/" + jobId + ": " + js);
+                if (js == null) {
+                    pw.print("unknown("); UserHandle.formatUid(pw, uid);
+                    pw.print("/jid"); pw.print(jobId); pw.println(")");
+                    return JobSchedulerShellCommand.CMD_ERR_NO_JOB;
+                }
+
+                boolean printed = false;
+                if (mPendingJobs.contains(js)) {
+                    pw.print("pending");
+                    printed = true;
+                }
+                if (isCurrentlyActiveLocked(js)) {
+                    if (printed) {
+                        pw.print(" ");
+                    }
+                    printed = true;
+                    pw.println("active");
+                }
+                if (!ArrayUtils.contains(mStartedUsers, js.getUserId())) {
+                    if (printed) {
+                        pw.print(" ");
+                    }
+                    printed = true;
+                    pw.println("user-stopped");
+                }
+                if (mBackingUpUids.indexOfKey(js.getSourceUid()) >= 0) {
+                    if (printed) {
+                        pw.print(" ");
+                    }
+                    printed = true;
+                    pw.println("backing-up");
+                }
+                boolean componentPresent = false;
+                try {
+                    componentPresent = (AppGlobals.getPackageManager().getServiceInfo(
+                            js.getServiceComponent(),
+                            PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
+                            js.getUserId()) != null);
+                } catch (RemoteException e) {
+                }
+                if (!componentPresent) {
+                    if (printed) {
+                        pw.print(" ");
+                    }
+                    printed = true;
+                    pw.println("no-component");
+                }
+                if (js.isReady()) {
+                    if (printed) {
+                        pw.print(" ");
+                    }
+                    printed = true;
+                    pw.println("ready");
+                }
+                if (!printed) {
+                    pw.print("waiting");
+                }
+                pw.println();
+            }
+        } catch (RemoteException e) {
+            // can't happen
+        }
+        return 0;
+    }
+
     private String printContextIdToJobMap(JobStatus[] map, String initial) {
         StringBuilder s = new StringBuilder(initial + ": ");
         for (int i=0; i<map.length; i++) {
@@ -2152,7 +2237,8 @@
         }
 
         final int filterUidFinal = UserHandle.getAppId(filterUid);
-        final long now = SystemClock.elapsedRealtime();
+        final long nowElapsed = SystemClock.elapsedRealtime();
+        final long nowUptime = SystemClock.uptimeMillis();
         synchronized (mLock) {
             mConstants.dump(pw);
             pw.println();
@@ -2184,7 +2270,7 @@
                         continue;
                     }
 
-                    job.dump(pw, "    ", true, now);
+                    job.dump(pw, "    ", true, nowElapsed);
                     pw.print("    Ready: ");
                     pw.print(isReadyToBeExecutedLocked(job));
                     pw.print(" (job=");
@@ -2254,14 +2340,14 @@
                 JobStatus job = mPendingJobs.get(i);
                 pw.print("  Pending #"); pw.print(i); pw.print(": ");
                 pw.println(job.toShortString());
-                job.dump(pw, "    ", false, now);
+                job.dump(pw, "    ", false, nowElapsed);
                 int priority = evaluateJobPriorityLocked(job);
                 if (priority != JobInfo.PRIORITY_DEFAULT) {
                     pw.print("    Evaluated priority: "); pw.println(priority);
                 }
                 pw.print("    Tag: "); pw.println(job.getTag());
                 pw.print("    Enq: ");
-                TimeUtils.formatDuration(job.madePending - now, pw);
+                TimeUtils.formatDuration(job.madePending - nowUptime, pw);
                 pw.println();
             }
             pw.println();
@@ -2276,17 +2362,17 @@
                 } else {
                     pw.println(job.toShortString());
                     pw.print("    Running for: ");
-                    TimeUtils.formatDuration(now - jsc.getExecutionStartTimeElapsed(), pw);
+                    TimeUtils.formatDuration(nowElapsed - jsc.getExecutionStartTimeElapsed(), pw);
                     pw.print(", timeout at: ");
-                    TimeUtils.formatDuration(jsc.getTimeoutElapsed() - now, pw);
+                    TimeUtils.formatDuration(jsc.getTimeoutElapsed() - nowElapsed, pw);
                     pw.println();
-                    job.dump(pw, "    ", false, now);
+                    job.dump(pw, "    ", false, nowElapsed);
                     int priority = evaluateJobPriorityLocked(jsc.getRunningJobLocked());
                     if (priority != JobInfo.PRIORITY_DEFAULT) {
                         pw.print("    Evaluated priority: "); pw.println(priority);
                     }
                     pw.print("    Active at ");
-                    TimeUtils.formatDuration(job.madeActive - now, pw);
+                    TimeUtils.formatDuration(job.madeActive - nowUptime, pw);
                     pw.print(", pending for ");
                     TimeUtils.formatDuration(job.madeActive - job.madePending, pw);
                     pw.println();
diff --git a/services/core/java/com/android/server/job/JobSchedulerShellCommand.java b/services/core/java/com/android/server/job/JobSchedulerShellCommand.java
index fdfb345..2d2f61f 100644
--- a/services/core/java/com/android/server/job/JobSchedulerShellCommand.java
+++ b/services/core/java/com/android/server/job/JobSchedulerShellCommand.java
@@ -60,6 +60,8 @@
                     return getStorageSeq(pw);
                 case "get-storage-not-low":
                     return getStorageNotLow(pw);
+                case "get-job-state":
+                    return getJobState(pw);
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -83,6 +85,43 @@
         }
     }
 
+    private boolean printError(int errCode, String pkgName, int userId, int jobId) {
+        PrintWriter pw;
+        switch (errCode) {
+            case CMD_ERR_NO_PACKAGE:
+                pw = getErrPrintWriter();
+                pw.print("Package not found: ");
+                pw.print(pkgName);
+                pw.print(" / user ");
+                pw.println(userId);
+                return true;
+
+            case CMD_ERR_NO_JOB:
+                pw = getErrPrintWriter();
+                pw.print("Could not find job ");
+                pw.print(jobId);
+                pw.print(" in package ");
+                pw.print(pkgName);
+                pw.print(" / user ");
+                pw.println(userId);
+                return true;
+
+            case CMD_ERR_CONSTRAINTS:
+                pw = getErrPrintWriter();
+                pw.print("Job ");
+                pw.print(jobId);
+                pw.print(" in package ");
+                pw.print(pkgName);
+                pw.print(" / user ");
+                pw.print(userId);
+                pw.println(" has functional constraints but --force not specified");
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
     private int runJob(PrintWriter pw) throws Exception {
         checkPermission("force scheduled jobs");
 
@@ -114,42 +153,17 @@
         final long ident = Binder.clearCallingIdentity();
         try {
             int ret = mInternal.executeRunCommand(pkgName, userId, jobId, force);
-            switch (ret) {
-                case CMD_ERR_NO_PACKAGE:
-                    pw.print("Package not found: ");
-                    pw.print(pkgName);
-                    pw.print(" / user ");
-                    pw.println(userId);
-                    break;
-
-                case CMD_ERR_NO_JOB:
-                    pw.print("Could not find job ");
-                    pw.print(jobId);
-                    pw.print(" in package ");
-                    pw.print(pkgName);
-                    pw.print(" / user ");
-                    pw.println(userId);
-                    break;
-
-                case CMD_ERR_CONSTRAINTS:
-                    pw.print("Job ");
-                    pw.print(jobId);
-                    pw.print(" in package ");
-                    pw.print(pkgName);
-                    pw.print(" / user ");
-                    pw.print(userId);
-                    pw.println(" has functional constraints but --force not specified");
-                    break;
-
-                default:
-                    // success!
-                    pw.print("Running job");
-                    if (force) {
-                        pw.print(" [FORCED]");
-                    }
-                    pw.println();
-                    break;
+            if (printError(ret, pkgName, userId, jobId)) {
+                return ret;
             }
+
+            // success!
+            pw.print("Running job");
+            if (force) {
+                pw.print(" [FORCED]");
+            }
+            pw.println();
+
             return ret;
         } finally {
             Binder.restoreCallingIdentity(ident);
@@ -244,6 +258,43 @@
         return 0;
     }
 
+    private int getJobState(PrintWriter pw) throws Exception {
+        checkPermission("force timeout jobs");
+
+        int userId = UserHandle.USER_SYSTEM;
+
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            switch (opt) {
+                case "-u":
+                case "--user":
+                    userId = UserHandle.parseUserArg(getNextArgRequired());
+                    break;
+
+                default:
+                    pw.println("Error: unknown option '" + opt + "'");
+                    return -1;
+            }
+        }
+
+        if (userId == UserHandle.USER_CURRENT) {
+            userId = ActivityManager.getCurrentUser();
+        }
+
+        final String pkgName = getNextArgRequired();
+        final String jobIdStr = getNextArgRequired();
+        final int jobId = Integer.parseInt(jobIdStr);
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            int ret = mInternal.getJobState(pw, pkgName, userId, jobId);
+            printError(ret, pkgName, userId, jobId);
+            return ret;
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
     @Override
     public void onHelp() {
         final PrintWriter pw = getOutPrintWriter();
@@ -277,6 +328,18 @@
         pw.println("    Return the last storage update sequence number that was received.");
         pw.println("  get-storage-not-low");
         pw.println("    Return whether storage is currently considered to not be low.");
+        pw.println("  get-job-state [-u | --user USER_ID] PACKAGE JOB_ID");
+        pw.println("    Return the current state of a job, may be any combination of:");
+        pw.println("      pending: currently on the pending list, waiting to be active");
+        pw.println("      active: job is actively running");
+        pw.println("      user-stopped: job can't run because its user is stopped");
+        pw.println("      backing-up: job can't run because app is currently backing up its data");
+        pw.println("      no-component: job can't run because its component is not available");
+        pw.println("      ready: job is ready to run (all constraints satisfied or bypassed)");
+        pw.println("      waiting: if nothing else above is printed, job not ready to run");
+        pw.println("    Options:");
+        pw.println("      -u or --user: specify which user's job is to be run; the default is");
+        pw.println("         the primary or system user");
         pw.println();
     }
 
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index 497d36f..22eed3b 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -35,6 +35,7 @@
 import android.util.Xml;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.server.IoThread;
 import com.android.server.job.controllers.JobStatus;
@@ -171,6 +172,14 @@
         return removed;
     }
 
+    /**
+     * Remove the jobs of users not specified in the whitelist.
+     * @param whitelist Array of User IDs whose jobs are not to be removed.
+     */
+    public void removeJobsOfNonUsers(int[] whitelist) {
+        mJobSet.removeJobsOfNonUsers(whitelist);
+    }
+
     @VisibleForTesting
     public void clear() {
         mJobSet.clear();
@@ -839,6 +848,17 @@
             return didRemove;
         }
 
+        // Remove the jobs all users not specified by the whitelist of user ids
+        public void removeJobsOfNonUsers(int[] whitelist) {
+            for (int jobIndex = mJobs.size() - 1; jobIndex >= 0; jobIndex--) {
+                int jobUserId = UserHandle.getUserId(mJobs.keyAt(jobIndex));
+                // check if job's user id is not in the whitelist
+                if (!ArrayUtils.contains(whitelist, jobUserId)) {
+                    mJobs.removeAt(jobIndex);
+                }
+            }
+        }
+
         public boolean contains(JobStatus job) {
             final int uid = job.getUid();
             ArraySet<JobStatus> jobs = mJobs.get(uid);
diff --git a/services/core/java/com/android/server/job/controllers/BatteryController.java b/services/core/java/com/android/server/job/controllers/BatteryController.java
index b1f8f6b..d275bd9 100644
--- a/services/core/java/com/android/server/job/controllers/BatteryController.java
+++ b/services/core/java/com/android/server/job/controllers/BatteryController.java
@@ -93,34 +93,31 @@
         }
     }
 
-    private void maybeReportNewChargingState() {
+    private void maybeReportNewChargingStateLocked() {
         final boolean stablePower = mChargeTracker.isOnStablePower();
         final boolean batteryNotLow = mChargeTracker.isBatteryNotLow();
         if (DEBUG) {
-            Slog.d(TAG, "maybeReportNewChargingState: " + stablePower);
+            Slog.d(TAG, "maybeReportNewChargingStateLocked: " + stablePower);
         }
         boolean reportChange = false;
-        synchronized (mLock) {
-            for (int i = mTrackedTasks.size() - 1; i >= 0; i--) {
-                final JobStatus ts = mTrackedTasks.valueAt(i);
-                boolean previous = ts.setChargingConstraintSatisfied(stablePower);
-                if (previous != stablePower) {
-                    reportChange = true;
-                }
-                previous = ts.setBatteryNotLowConstraintSatisfied(batteryNotLow);
-                if (previous != batteryNotLow) {
-                    reportChange = true;
-                }
+        for (int i = mTrackedTasks.size() - 1; i >= 0; i--) {
+            final JobStatus ts = mTrackedTasks.valueAt(i);
+            boolean previous = ts.setChargingConstraintSatisfied(stablePower);
+            if (previous != stablePower) {
+                reportChange = true;
+            }
+            previous = ts.setBatteryNotLowConstraintSatisfied(batteryNotLow);
+            if (previous != batteryNotLow) {
+                reportChange = true;
             }
         }
-        // Let the scheduler know that state has changed. This may or may not result in an
-        // execution.
-        if (reportChange) {
-            mStateChangedListener.onControllerStateChanged();
-        }
-        // Also tell the scheduler that any ready jobs should be flushed.
         if (stablePower || batteryNotLow) {
+            // If one of our conditions has been satisfied, always schedule any newly ready jobs.
             mStateChangedListener.onRunJobNow(null);
+        } else if (reportChange) {
+            // Otherwise, just let the job scheduler know the state has changed and take care of it
+            // as it thinks is best.
+            mStateChangedListener.onControllerStateChanged();
         }
     }
 
@@ -201,38 +198,42 @@
 
         @VisibleForTesting
         public void onReceiveInternal(Intent intent) {
-            final String action = intent.getAction();
-            if (Intent.ACTION_BATTERY_LOW.equals(action)) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Battery life too low to do work. @ "
-                            + SystemClock.elapsedRealtime());
+            synchronized (mLock) {
+                final String action = intent.getAction();
+                if (Intent.ACTION_BATTERY_LOW.equals(action)) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "Battery life too low to do work. @ "
+                                + SystemClock.elapsedRealtime());
+                    }
+                    // If we get this action, the battery is discharging => it isn't plugged in so
+                    // there's no work to cancel. We track this variable for the case where it is
+                    // charging, but hasn't been for long enough to be healthy.
+                    mBatteryHealthy = false;
+                    maybeReportNewChargingStateLocked();
+                } else if (Intent.ACTION_BATTERY_OKAY.equals(action)) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "Battery life healthy enough to do work. @ "
+                                + SystemClock.elapsedRealtime());
+                    }
+                    mBatteryHealthy = true;
+                    maybeReportNewChargingStateLocked();
+                } else if (BatteryManager.ACTION_CHARGING.equals(action)) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "Received charging intent, fired @ "
+                                + SystemClock.elapsedRealtime());
+                    }
+                    mCharging = true;
+                    maybeReportNewChargingStateLocked();
+                } else if (BatteryManager.ACTION_DISCHARGING.equals(action)) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "Disconnected from power.");
+                    }
+                    mCharging = false;
+                    maybeReportNewChargingStateLocked();
                 }
-                // If we get this action, the battery is discharging => it isn't plugged in so
-                // there's no work to cancel. We track this variable for the case where it is
-                // charging, but hasn't been for long enough to be healthy.
-                mBatteryHealthy = false;
-            } else if (Intent.ACTION_BATTERY_OKAY.equals(action)) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Battery life healthy enough to do work. @ "
-                            + SystemClock.elapsedRealtime());
-                }
-                mBatteryHealthy = true;
-                maybeReportNewChargingState();
-            } else if (BatteryManager.ACTION_CHARGING.equals(action)) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Received charging intent, fired @ "
-                            + SystemClock.elapsedRealtime());
-                }
-                mCharging = true;
-                maybeReportNewChargingState();
-            } else if (BatteryManager.ACTION_DISCHARGING.equals(action)) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Disconnected from power.");
-                }
-                mCharging = false;
-                maybeReportNewChargingState();
+                mLastBatterySeq = intent.getIntExtra(BatteryManager.EXTRA_SEQUENCE,
+                        mLastBatterySeq);
             }
-            mLastBatterySeq = intent.getIntExtra(BatteryManager.EXTRA_SEQUENCE, mLastBatterySeq);
         }
     }
 
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 45971f5..4a45c07 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -943,9 +943,9 @@
                     long time = mNtpTime.getCachedNtpTime();
                     long timeReference = mNtpTime.getCachedNtpTimeReference();
                     long certainty = mNtpTime.getCacheCertainty();
-                    long now = System.currentTimeMillis();
 
                     if (DEBUG) {
+                        long now = System.currentTimeMillis();
                         Log.d(TAG, "NTP server returned: "
                                 + time + " (" + new Date(time)
                                 + ") reference: " + timeReference
@@ -1458,7 +1458,7 @@
 
             // reset SV count to zero
             updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0, 0, 0);
-            mFixRequestTime = System.currentTimeMillis();
+            mFixRequestTime = SystemClock.elapsedRealtime();
             if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
                 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
                 // and our fix interval is not short
@@ -1535,12 +1535,12 @@
                 mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());
             }
             if (mTimeToFirstFix > 0) {
-                int timeBetweenFixes = (int) (System.currentTimeMillis() - mLastFixTime);
+                int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);
                 mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);
             }
         }
 
-        mLastFixTime = System.currentTimeMillis();
+        mLastFixTime = SystemClock.elapsedRealtime();
         // report time to first fix
         if (mTimeToFirstFix == 0 && hasLatLong) {
             mTimeToFirstFix = (int)(mLastFixTime - mFixRequestTime);
@@ -1665,7 +1665,7 @@
         updateStatus(mStatus, usedInFixCount, meanCn0, maxCn0);
 
         if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
-            System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT) {
+            SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) {
             // send an intent to notify that the GPS is no longer receiving fixes.
             Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
             intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false);
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index f8b72e2..8753a3a 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -150,12 +150,12 @@
     private final NotificationManager mNotificationManager;
     private final UserManager mUserManager;
     private final IActivityManager mActivityManager;
+    private final SyntheticPasswordManager mSpManager;
 
     private final KeyStore mKeyStore;
 
     private boolean mFirstCallToVold;
     protected IGateKeeperService mGateKeeperService;
-    private SyntheticPasswordManager mSpManager;
 
     /**
      * The UIDs that are used for system credential storage in keystore.
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
index 861209d..d621a68 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
@@ -26,6 +26,7 @@
 import android.database.sqlite.SQLiteOpenHelper;
 import android.os.Environment;
 import android.os.UserManager;
+import android.os.storage.StorageManager;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
@@ -339,8 +340,11 @@
         synchronized (mFileWriteLock) {
             RandomAccessFile raf = null;
             try {
-                // Write the hash to file
-                raf = new RandomAccessFile(name, "rw");
+                // Write the hash to file, requiring each write to be synchronized to the
+                // underlying storage device immediately to avoid data loss in case of power loss.
+                // This also ensures future secdiscard operation on the file succeeds since the
+                // file would have been allocated on flash.
+                raf = new RandomAccessFile(name, "rws");
                 // Truncate the file if pattern is null, to clear the lock
                 if (hash == null || hash.length == 0) {
                     raf.setLength(0);
@@ -435,12 +439,17 @@
         return readFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name));
     }
 
-    public void deleteSyntheticPasswordState(int userId, long handle, String name, boolean secure) {
+    public void deleteSyntheticPasswordState(int userId, long handle, String name) {
         String path = getSynthenticPasswordStateFilePathForUser(userId, handle, name);
         File file = new File(path);
         if (file.exists()) {
-            //TODO: (b/34600579) invoke secdiscardable
-            file.delete();
+            try {
+                mContext.getSystemService(StorageManager.class).secdiscard(file.getAbsolutePath());
+            } catch (Exception e) {
+                Slog.w(TAG, "Failed to secdiscard " + path, e);
+            } finally {
+                file.delete();
+            }
             mCache.putFile(path, null);
         }
     }
@@ -546,7 +555,7 @@
         void initialize(SQLiteDatabase db);
     }
 
-    class DatabaseHelper extends SQLiteOpenHelper {
+    static class DatabaseHelper extends SQLiteOpenHelper {
         private static final String TAG = "LockSettingsDB";
         private static final String DATABASE_NAME = "locksettings.db";
 
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index e2ec92b..2f8a1b4 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -452,7 +452,7 @@
 
     // Nuke the SP handle (and as a result, its SID) for the given user.
     public void clearSidForUser(int userId) {
-        destroyState(SP_HANDLE_NAME, true, DEFAULT_HANDLE, userId);
+        destroyState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
     }
 
     public boolean hasSidForUser(int userId) {
@@ -487,8 +487,8 @@
     }
 
     public void destroyEscrowData(int userId) {
-        destroyState(SP_E0_NAME, true, DEFAULT_HANDLE, userId);
-        destroyState(SP_P1_NAME, true, DEFAULT_HANDLE, userId);
+        destroyState(SP_E0_NAME, DEFAULT_HANDLE, userId);
+        destroyState(SP_P1_NAME, DEFAULT_HANDLE, userId);
     }
 
     private int loadWeaverSlot(long handle, int userId) {
@@ -523,7 +523,7 @@
                 Log.w(TAG, "Failed to destroy slot", e);
             }
         }
-        destroyState(WEAVER_SLOT_NAME, true, handle, userId);
+        destroyState(WEAVER_SLOT_NAME, handle, userId);
     }
 
     private int getNextAvailableWeaverSlot() {
@@ -877,17 +877,17 @@
 
     public void destroyTokenBasedSyntheticPassword(long handle, int userId) {
         destroySyntheticPassword(handle, userId);
-        destroyState(SECDISCARDABLE_NAME, true, handle, userId);
+        destroyState(SECDISCARDABLE_NAME, handle, userId);
     }
 
     public void destroyPasswordBasedSyntheticPassword(long handle, int userId) {
         destroySyntheticPassword(handle, userId);
-        destroyState(SECDISCARDABLE_NAME, true, handle, userId);
-        destroyState(PASSWORD_DATA_NAME, true, handle, userId);
+        destroyState(SECDISCARDABLE_NAME, handle, userId);
+        destroyState(PASSWORD_DATA_NAME, handle, userId);
     }
 
     private void destroySyntheticPassword(long handle, int userId) {
-        destroyState(SP_BLOB_NAME, true, handle, userId);
+        destroyState(SP_BLOB_NAME, handle, userId);
         destroySPBlobKey(getHandleName(handle));
         if (hasState(WEAVER_SLOT_NAME, handle, userId)) {
             destroyWeaverSlot(handle, userId);
@@ -938,8 +938,8 @@
         mStorage.writeSyntheticPasswordState(userId, handle, stateName, data);
     }
 
-    private void destroyState(String stateName, boolean secure, long handle, int userId) {
-        mStorage.deleteSyntheticPasswordState(userId, handle, stateName, secure);
+    private void destroyState(String stateName, long handle, int userId) {
+        mStorage.deleteSyntheticPasswordState(userId, handle, stateName);
     }
 
     protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 5a5e658..803b0dc 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -153,7 +153,7 @@
                   final ApplicationInfo applicationInfo =
                         mContext.getPackageManager().getApplicationInfoAsUser(sbn.getPackageName(),
                                 0, UserHandle.getUserId(sbn.getUid()));
-                if (applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
+                if (applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
                     return true;
                 }
             }
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index e83d453..f00ef38 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -286,7 +286,7 @@
     private boolean shouldHaveDefaultChannel(Record r) throws NameNotFoundException {
         final int userId = UserHandle.getUserId(r.uid);
         final ApplicationInfo applicationInfo = mPm.getApplicationInfoAsUser(r.pkg, 0, userId);
-        if (applicationInfo.targetSdkVersion > Build.VERSION_CODES.N_MR1) {
+        if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.O) {
             // O apps should not have the default channel.
             return false;
         }
@@ -1158,6 +1158,9 @@
 
     public boolean badgingEnabled(UserHandle userHandle) {
         int userId = userHandle.getIdentifier();
+        if (userId == UserHandle.USER_ALL) {
+            return false;
+        }
         if (mBadgingEnabled.indexOfKey(userId) < 0) {
             mBadgingEnabled.put(userId,
                     Secure.getIntForUser(mContext.getContentResolver(),
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index 1de3936..562ab33 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -96,7 +96,7 @@
                 return mGetEphemeralResolveInfoCaller
                         .getEphemeralResolveInfoList(target, hashPrefix, token);
             } catch (TimeoutException e) {
-                throw new ConnectionException(ConnectionException.FAILURE_BIND);
+                throw new ConnectionException(ConnectionException.FAILURE_CALL);
             } catch (RemoteException ignore) {
             }
         } finally {
diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java
index 85be4a2..34cc6e3 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolver.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolver.java
@@ -182,6 +182,7 @@
                     failureIntent = null;
                 }
                 final Intent installerIntent = buildEphemeralInstallerIntent(
+                        Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE,
                         requestObj.origIntent,
                         failureIntent,
                         requestObj.callingPackage,
@@ -226,6 +227,7 @@
      * Builds and returns an intent to launch the instant installer.
      */
     public static Intent buildEphemeralInstallerIntent(
+            @NonNull String action,
             @NonNull Intent origIntent,
             @NonNull Intent failureIntent,
             @NonNull String callingPackage,
@@ -239,7 +241,7 @@
             boolean needsPhaseTwo) {
         // Construct the intent that launches the instant installer
         int flags = origIntent.getFlags();
-        final Intent intent = new Intent();
+        final Intent intent = new Intent(action);
         intent.setFlags(flags
                 | Intent.FLAG_ACTIVITY_NEW_TASK
                 | Intent.FLAG_ACTIVITY_CLEAR_TASK
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c7a8346..bf30d7a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2027,15 +2027,17 @@
             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
                     getUnknownSourcesSettings());
 
-            // Force a gc to clear up things
-            Runtime.getRuntime().gc();
-
             // Remove the replaced package's older resources safely now
             // We delete after a gc for applications  on sdcard.
             if (res.removedInfo != null && res.removedInfo.args != null) {
+                Runtime.getRuntime().gc();
                 synchronized (mInstallLock) {
                     res.removedInfo.args.doPostDeleteLI(true);
                 }
+            } else {
+                // Force a gc to clear up things. Ask for a background one, it's fine to go on
+                // and not block here.
+                VMRuntime.getRuntime().requestConcurrentGC();
             }
 
             // Notify DexManager that the package was installed for new users.
@@ -3481,28 +3483,49 @@
         return cur;
     }
 
+    /**
+     * Returns whether or not a full application can see an instant application.
+     * <p>
+     * Currently, there are three cases in which this can occur:
+     * <ol>
+     * <li>The calling application is a "special" process. The special
+     *     processes are {@link Process#SYSTEM_UID}, {@link Process#SHELL_UID}
+     *     and {@code 0}</li>
+     * <li>The calling application has the permission
+     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}</li>
+     * <li>[TODO] The calling application is the default launcher on the
+     *     system partition.</li>
+     * </ol>
+     */
+    private boolean canAccessInstantApps(int callingUid) {
+        final boolean isSpecialProcess =
+                callingUid == Process.SYSTEM_UID
+                        || callingUid == Process.SHELL_UID
+                        || callingUid == 0;
+        final boolean allowMatchInstant =
+                isSpecialProcess
+                        || mContext.checkCallingOrSelfPermission(
+                        android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED;
+        return allowMatchInstant;
+    }
     private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
         if (ps == null) {
             return null;
         }
-        final PackageParser.Package p = ps.pkg;
+        PackageParser.Package p = ps.pkg;
         if (p == null) {
             return null;
         }
+        final int callingUid =  Binder.getCallingUid();
         // Filter out ephemeral app metadata:
         //   * The system/shell/root can see metadata for any app
         //   * An installed app can see metadata for 1) other installed apps
         //     and 2) ephemeral apps that have explicitly interacted with it
         //   * Ephemeral apps can only see their own data and exposed installed apps
         //   * Holding a signature permission allows seeing instant apps
-        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
-        if (callingAppId != Process.SYSTEM_UID
-                && callingAppId != Process.SHELL_UID
-                && callingAppId != Process.ROOT_UID
-                && checkUidPermission(Manifest.permission.ACCESS_INSTANT_APPS,
-                        Binder.getCallingUid()) != PackageManager.PERMISSION_GRANTED) {
-            final String instantAppPackageName = getInstantAppPackageName(Binder.getCallingUid());
+        if (!canAccessInstantApps(callingUid)) {
+            final String instantAppPackageName = getInstantAppPackageName(callingUid);
             if (instantAppPackageName != null) {
                 // ephemeral apps can only get information on themselves or
                 // installed apps that are exposed.
@@ -3513,6 +3536,7 @@
             } else {
                 if (ps.getInstantApp(userId)) {
                     // only get access to the ephemeral app if we've been granted access
+                    final int callingAppId = UserHandle.getAppId(callingUid);
                     if (!mInstantAppRegistry.isInstantAccessGranted(
                             userId, callingAppId, ps.appId)) {
                         return null;
@@ -3617,8 +3641,9 @@
     private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
             int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
+        final int callingUid = Binder.getCallingUid();
         flags = updateFlagsForPackage(flags, userId, packageName);
-        enforceCrossUserPermission(Binder.getCallingUid(), userId,
+        enforceCrossUserPermission(callingUid, userId,
                 false /* requireFullPermission */, false /* checkShell */, "get package info");
 
         // reader
@@ -3630,7 +3655,10 @@
             if (matchFactoryOnly) {
                 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
                 if (ps != null) {
-                    if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
+                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
+                        return null;
+                    }
+                    if (filterAppAccessLPr(ps, callingUid, userId)) {
                         return null;
                     }
                     return generatePackageInfo(ps, flags, userId);
@@ -3644,15 +3672,22 @@
             if (DEBUG_PACKAGE_INFO)
                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
             if (p != null) {
-                if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
-                        Binder.getCallingUid(), userId, flags)) {
+                final PackageSetting ps = (PackageSetting) p.mExtras;
+                if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
+                    return null;
+                }
+                if (ps != null && filterAppAccessLPr(ps, callingUid, userId)) {
                     return null;
                 }
                 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
             }
             if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
                 final PackageSetting ps = mSettings.mPackages.get(packageName);
-                if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
+                if (ps == null) return null;
+                if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
+                    return null;
+                }
+                if (filterAppAccessLPr(ps, callingUid, userId)) {
                     return null;
                 }
                 return generatePackageInfo(ps, flags, userId);
@@ -3661,6 +3696,57 @@
         return null;
     }
 
+    /**
+     * Returns whether or not access to the application should be filtered.
+     * <p>
+     * Access may be limited based upon whether the calling or target applications
+     * are instant applications.
+     *
+     * @see #canAccessInstantApps(int)
+     */
+    private boolean filterAppAccessLPr(@NonNull PackageSetting ps, int callingUid,
+            @Nullable ComponentName component, boolean componentVisibleToInstantApp, int userId) {
+        // if we're in an isolated process, get the real calling UID
+        if (Process.isIsolated(callingUid)) {
+            callingUid = mIsolatedOwners.get(callingUid);
+        }
+        // if the target and caller are the same application, don't filter
+        if (isCallerSameApp(ps.name, callingUid)) {
+            return false;
+        }
+        final String instantAppPkgName = getInstantAppPackageName(callingUid);
+        final boolean callerIsInstantApp = instantAppPkgName != null;
+        if (callerIsInstantApp) {
+            // request for a specific component; if it hasn't been explicitly exposed, filter
+            if (component != null) {
+                return !componentVisibleToInstantApp;
+            }
+            // request for application; if no components have been explicitly exposed, filter
+            return !ps.pkg.visibleToInstantApps;
+        }
+        if (ps.getInstantApp(userId)) {
+            // caller can see all components of all instant applications, don't filter
+            if (canAccessInstantApps(callingUid)) {
+                return false;
+            }
+            // request for a specific instant application component, filter
+            if (component != null) {
+                return true;
+            }
+            // request for an instant application; if the caller hasn't been granted access, filter
+            return !mInstantAppRegistry.isInstantAccessGranted(
+                    userId, UserHandle.getAppId(callingUid), ps.appId);
+        }
+        return false;
+    }
+
+    /**
+     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
+     */
+    private boolean filterAppAccessLPr(@NonNull PackageSetting ps, int callingUid, int userId) {
+        return filterAppAccessLPr(ps, callingUid, null, false, userId);
+    }
+
     private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
             int flags) {
         // Callers can access only the libs they depend on, otherwise they need to explicitly
@@ -3869,6 +3955,9 @@
             if (filterSharedLibPackageLPr(ps, uid, userId, flags)) {
                 return null;
             }
+            if (filterAppAccessLPr(ps, uid, userId)) {
+                return null;
+            }
             if (ps.pkg == null) {
                 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
                 if (pInfo != null) {
@@ -3910,6 +3999,9 @@
                 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
                     return null;
                 }
+                if (filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
+                    return null;
+                }
                 // Note: isEnabledLP() does not apply here - always return info
                 ApplicationInfo ai = PackageParser.generateApplicationInfo(
                         p, flags, ps.readUserState(userId), userId);
@@ -4209,15 +4301,15 @@
      */
     int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
         return updateFlagsForResolve(flags, userId, intent, callingUid,
-                false /*includeInstantApps*/, false /*onlyExposedExplicitly*/);
+                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
     }
     int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
-            boolean includeInstantApps) {
+            boolean wantInstantApps) {
         return updateFlagsForResolve(flags, userId, intent, callingUid,
-                includeInstantApps, false /*onlyExposedExplicitly*/);
+                wantInstantApps, false /*onlyExposedExplicitly*/);
     }
     int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
-            boolean includeInstantApps, boolean onlyExposedExplicitly) {
+            boolean wantInstantApps, boolean onlyExposedExplicitly) {
         // Safe mode means we shouldn't match any third-party components
         if (mSafeMode) {
             flags |= PackageManager.MATCH_SYSTEM_ONLY;
@@ -4230,18 +4322,11 @@
             flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
             flags |= PackageManager.MATCH_INSTANT;
         } else {
-            // Otherwise, prevent leaking ephemeral components
-            final boolean isSpecialProcess =
-                    callingUid == Process.SYSTEM_UID
-                    || callingUid == Process.SHELL_UID
-                    || callingUid == 0;
             final boolean allowMatchInstant =
-                    (includeInstantApps
+                    (wantInstantApps
                             && Intent.ACTION_VIEW.equals(intent.getAction())
                             && hasWebURI(intent))
-                    || isSpecialProcess
-                    || mContext.checkCallingOrSelfPermission(
-                            android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED;
+                    || canAccessInstantApps(callingUid);
             flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
                     | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
             if (!allowMatchInstant) {
@@ -4272,8 +4357,9 @@
     @Override
     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
+        final int callingUid = Binder.getCallingUid();
         flags = updateFlagsForComponent(flags, userId, component);
-        enforceCrossUserPermission(Binder.getCallingUid(), userId,
+        enforceCrossUserPermission(callingUid, userId,
                 false /* requireFullPermission */, false /* checkShell */, "get activity info");
         synchronized (mPackages) {
             PackageParser.Activity a = mActivities.mActivities.get(component);
@@ -4282,6 +4368,11 @@
             if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
                 if (ps == null) return null;
+                final boolean visibleToInstantApp =
+                        (a.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
+                if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) {
+                    return null;
+                }
                 return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
             }
             if (mResolveComponentName.equals(component)) {
@@ -4446,8 +4537,9 @@
     @Override
     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
+        final int callingUid = Binder.getCallingUid();
         flags = updateFlagsForComponent(flags, userId, component);
-        enforceCrossUserPermission(Binder.getCallingUid(), userId,
+        enforceCrossUserPermission(callingUid, userId,
                 false /* requireFullPermission */, false /* checkShell */, "get service info");
         synchronized (mPackages) {
             PackageParser.Service s = mServices.mServices.get(component);
@@ -4456,6 +4548,11 @@
             if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
                 if (ps == null) return null;
+                final boolean visibleToInstantApp =
+                        (s.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
+                if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) {
+                    return null;
+                }
                 ServiceInfo si = PackageParser.generateServiceInfo(s, flags,
                         ps.readUserState(userId), userId);
                 if (si != null) {
@@ -4470,8 +4567,9 @@
     @Override
     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
+        final int callingUid = Binder.getCallingUid();
         flags = updateFlagsForComponent(flags, userId, component);
-        enforceCrossUserPermission(Binder.getCallingUid(), userId,
+        enforceCrossUserPermission(callingUid, userId,
                 false /* requireFullPermission */, false /* checkShell */, "get provider info");
         synchronized (mPackages) {
             PackageParser.Provider p = mProviders.mProviders.get(component);
@@ -4480,6 +4578,11 @@
             if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
                 if (ps == null) return null;
+                final boolean visibleToInstantApp =
+                        (p.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
+                if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) {
+                    return null;
+                }
                 ProviderInfo pi = PackageParser.generateProviderInfo(p, flags,
                         ps.readUserState(userId), userId);
                 if (pi != null) {
@@ -6492,18 +6595,22 @@
                 }
             } else {
                 final PackageParser.Package pkg = mPackages.get(pkgName);
+                result = null;
                 if (pkg != null) {
-                    return applyPostResolutionFilter(filterIfNotSystemUser(
+                    result = filterIfNotSystemUser(
                             mActivities.queryIntentForPackage(
                                     intent, resolvedType, flags, pkg.activities, userId),
-                            userId), instantAppPkgName);
-                } else {
+                            userId);
+                }
+                if (result == null || result.size() == 0) {
                     // the caller wants to resolve for a particular package; however, there
                     // were no installed results, so, try to find an ephemeral result
                     addEphemeral = !ephemeralDisabled
                             && isInstantAppAllowed(
                                     intent, null /*result*/, userId, true /*skipPackageCheck*/);
-                    result = new ArrayList<ResolveInfo>();
+                    if (result == null) {
+                        result = new ArrayList<>();
+                    }
                 }
             }
         }
@@ -17473,17 +17580,24 @@
                 }
             }
 
-            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
-            // Do not run PackageDexOptimizer through the local performDexOpt
-            // method because `pkg` may not be in `mPackages` yet.
-            //
-            // Also, don't fail application installs if the dexopt step fails.
-            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
-                    null /* instructionSets */, false /* checkProfiles */,
-                    getCompilerFilterForReason(REASON_INSTALL),
-                    getOrCreateCompilerPackageStats(pkg),
-                    mDexManager.isUsedByOtherApps(pkg.packageName));
-            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+            // dexopt can take some time to complete, so, for instant apps, we skip this
+            // step during installation. Instead, we'll take extra time the first time the
+            // instant app starts. It's preferred to do it this way to provide continuous
+            // progress to the user instead of mysteriously blocking somewhere in the
+            // middle of running an instant app.
+            if (!instantApp) {
+                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
+                // Do not run PackageDexOptimizer through the local performDexOpt
+                // method because `pkg` may not be in `mPackages` yet.
+                //
+                // Also, don't fail application installs if the dexopt step fails.
+                mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
+                        null /* instructionSets */, false /* checkProfiles */,
+                        getCompilerFilterForReason(REASON_INSTALL),
+                        getOrCreateCompilerPackageStats(pkg),
+                        mDexManager.isUsedByOtherApps(pkg.packageName));
+                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+            }
 
             // Notify BackgroundDexOptService that the package has been changed.
             // If this is an update of a package which used to fail to compile,
@@ -23898,6 +24012,11 @@
                 return getUidTargetSdkVersionLockedLPr(uid);
             }
         }
+
+        @Override
+        public boolean canAccessInstantApps(int callingUid) {
+            return PackageManagerService.this.canAccessInstantApps(callingUid);
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 44bcff2..24cbdbf 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -987,11 +987,11 @@
         // Update static shared library dependencies if needed
         if (pkg.usesStaticLibraries != null && pkg.usesStaticLibrariesVersions != null
                 && pkg.usesStaticLibraries.size() == pkg.usesStaticLibrariesVersions.length) {
-            String[] usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
-            pkg.usesStaticLibraries.toArray(usesStaticLibraries);
+            p.usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
+            pkg.usesStaticLibraries.toArray(p.usesStaticLibraries);
             p.usesStaticLibrariesVersions = pkg.usesStaticLibrariesVersions;
         } else {
-            pkg.usesStaticLibraries = null;
+            p.usesStaticLibraries = null;
             p.usesStaticLibrariesVersions = null;
         }
         addPackageSettingLPw(p, p.sharedUser);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 30c4009..b115422 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -3684,6 +3684,11 @@
         }
 
         @Override
+        public int[] getUserIds() {
+            return UserManagerService.this.getUserIds();
+        }
+
+        @Override
         public boolean isUserUnlockingOrUnlocked(int userId) {
             synchronized (mUserStates) {
                 int state = mUserStates.get(userId, -1);
diff --git a/services/core/java/com/android/server/policy/LegacyGlobalActions.java b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
index a71bc4c..14fabc5 100644
--- a/services/core/java/com/android/server/policy/LegacyGlobalActions.java
+++ b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
@@ -228,6 +228,7 @@
                 R.string.global_actions_airplane_mode_on_status,
                 R.string.global_actions_airplane_mode_off_status) {
 
+            @Override
             void onToggle(boolean on) {
                 if (mHasTelephony && Boolean.parseBoolean(
                         SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
@@ -254,10 +255,12 @@
                 }
             }
 
+            @Override
             public boolean showDuringKeyguard() {
                 return true;
             }
 
+            @Override
             public boolean showBeforeProvisioning() {
                 return false;
             }
@@ -457,6 +460,7 @@
             return false;
         }
 
+        @Override
         public boolean showDuringKeyguard() {
             return true;
         }
@@ -616,6 +620,7 @@
                             com.android.internal.R.drawable.ic_menu_cc, icon,
                             (user.name != null ? user.name : "Primary")
                             + (isCurrentUser ? " \u2714" : "")) {
+                        @Override
                         public void onPress() {
                             try {
                                 ActivityManager.getService().switchUser(user.id);
@@ -624,10 +629,12 @@
                             }
                         }
 
+                        @Override
                         public boolean showDuringKeyguard() {
                             return true;
                         }
 
+                        @Override
                         public boolean showBeforeProvisioning() {
                             return false;
                         }
@@ -659,6 +666,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public void onDismiss(DialogInterface dialog) {
         if (mOnDismiss != null) {
             mOnDismiss.run();
@@ -674,6 +682,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public void onClick(DialogInterface dialog, int which) {
         if (!(mAdapter.getItem(which) instanceof SilentModeTriStateAction)) {
             dialog.dismiss();
@@ -689,6 +698,7 @@
      */
     private class MyAdapter extends BaseAdapter {
 
+        @Override
         public int getCount() {
             int count = 0;
 
@@ -716,6 +726,7 @@
             return false;
         }
 
+        @Override
         public Action getItem(int position) {
 
             int filteredPos = 0;
@@ -740,11 +751,12 @@
                     + ", provisioned=" + mDeviceProvisioned);
         }
 
-
+        @Override
         public long getItemId(int position) {
             return position;
         }
 
+        @Override
         public View getView(int position, View convertView, ViewGroup parent) {
             Action action = getItem(position);
             return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
@@ -817,6 +829,7 @@
             mIcon = icon;
         }
 
+        @Override
         public boolean isEnabled() {
             return true;
         }
@@ -825,8 +838,10 @@
             return null;
         }
 
+        @Override
         abstract public void onPress();
 
+        @Override
         public CharSequence getLabelForAccessibility(Context context) {
             if (mMessage != null) {
                 return mMessage;
@@ -835,6 +850,7 @@
             }
         }
 
+        @Override
         public View create(
                 Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
             View v = inflater.inflate(R.layout.global_actions_item, parent, false);
@@ -929,6 +945,7 @@
             return context.getString(mMessageResId);
         }
 
+        @Override
         public View create(Context context, View convertView, ViewGroup parent,
                 LayoutInflater inflater) {
             willCreate();
@@ -963,6 +980,7 @@
             return v;
         }
 
+        @Override
         public final void onPress() {
             if (mState.inTransition()) {
                 Log.w(TAG, "shouldn't be able to toggle when in transition");
@@ -974,6 +992,7 @@
             changeStateFromPress(nowOn);
         }
 
+        @Override
         public boolean isEnabled() {
             return !mState.inTransition();
         }
@@ -1004,6 +1023,7 @@
                     R.string.global_action_silent_mode_off_status);
         }
 
+        @Override
         void onToggle(boolean on) {
             if (on) {
                 mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
@@ -1012,10 +1032,12 @@
             }
         }
 
+        @Override
         public boolean showDuringKeyguard() {
             return true;
         }
 
+        @Override
         public boolean showBeforeProvisioning() {
             return false;
         }
@@ -1050,6 +1072,7 @@
             return null;
         }
 
+        @Override
         public View create(Context context, View convertView, ViewGroup parent,
                 LayoutInflater inflater) {
             View v = inflater.inflate(R.layout.global_actions_silent_mode, parent, false);
@@ -1065,17 +1088,21 @@
             return v;
         }
 
+        @Override
         public void onPress() {
         }
 
+        @Override
         public boolean showDuringKeyguard() {
             return true;
         }
 
+        @Override
         public boolean showBeforeProvisioning() {
             return false;
         }
 
+        @Override
         public boolean isEnabled() {
             return true;
         }
@@ -1083,6 +1110,7 @@
         void willCreate() {
         }
 
+        @Override
         public void onClick(View v) {
             if (!(v.getTag() instanceof Integer)) return;
 
@@ -1093,6 +1121,7 @@
     }
 
     private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
             if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
@@ -1146,6 +1175,7 @@
     private static final int DIALOG_DISMISS_DELAY = 300; // ms
 
     private Handler mHandler = new Handler() {
+        @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
             case MESSAGE_DISMISS:
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 6f5c070c..87ce6c9 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -234,6 +234,7 @@
 import com.android.internal.widget.PointerLocationView;
 import com.android.server.GestureLauncherService;
 import com.android.server.LocalServices;
+import com.android.server.SystemServiceManager;
 import com.android.server.policy.keyguard.KeyguardServiceDelegate;
 import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener;
 import com.android.server.policy.keyguard.KeyguardStateMonitor.StateCallback;
@@ -476,6 +477,7 @@
 
     boolean mBootMessageNeedsHiding;
     KeyguardServiceDelegate mKeyguardDelegate;
+    private boolean mKeyguardBound;
     final Runnable mWindowManagerDrawCallback = new Runnable() {
         @Override
         public void run() {
@@ -530,7 +532,6 @@
 
     boolean mSystemReady;
     boolean mSystemBooted;
-    private boolean mDeferBindKeyguard;
     boolean mHdmiPlugged;
     HdmiControl mHdmiControl;
     IUiModeManager mUiModeManager;
@@ -1328,7 +1329,7 @@
                 Message msg = mHandler.obtainMessage(MSG_POWER_DELAYED_PRESS,
                         interactive ? 1 : 0, mPowerKeyPressCounter, eventTime);
                 msg.setAsynchronous(true);
-                mHandler.sendMessageDelayed(msg, ViewConfiguration.getDoubleTapTimeout());
+                mHandler.sendMessageDelayed(msg, ViewConfiguration.getMultiPressTimeout());
                 return;
             }
 
@@ -2087,6 +2088,13 @@
                 handleStartTransitionForKeyguardLw(transit, null /* transit */);
             }
         });
+        mKeyguardDelegate = new KeyguardServiceDelegate(mContext,
+                new StateCallback() {
+                    @Override
+                    public void onTrustedChanged() {
+                        mWindowManagerFuncs.notifyKeyguardTrustedChanged();
+                    }
+                });
     }
 
     /**
@@ -6631,6 +6639,13 @@
         reportScreenStateToVrManager(false);
     }
 
+    private long getKeyguardDrawnTimeout() {
+        final boolean bootCompleted =
+                LocalServices.getService(SystemServiceManager.class).isBootCompleted();
+        // Set longer timeout if it has not booted yet to prevent showing empty window.
+        return bootCompleted ? 1000 : 5000;
+    }
+
     // Called on the DisplayManager's DisplayPowerController thread.
     @Override
     public void screenTurningOn(final ScreenOnListener screenOnListener) {
@@ -6646,7 +6661,8 @@
 
             if (mKeyguardDelegate != null) {
                 mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
-                mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000);
+                mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT,
+                        getKeyguardDrawnTimeout());
                 mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);
             } else {
                 if (DEBUG_WAKEUP) Slog.d(TAG,
@@ -6667,6 +6683,11 @@
         reportScreenStateToVrManager(true);
     }
 
+    @Override
+    public void screenTurningOff(ScreenOffListener screenOffListener) {
+        mWindowManagerFuncs.screenTurningOff(screenOffListener);
+    }
+
     private void reportScreenStateToVrManager(boolean isScreenOn) {
         if (mVrManagerInternal == null) {
             return;
@@ -7154,16 +7175,26 @@
         return out;
     }
 
+    private void bindKeyguard() {
+        synchronized (mLock) {
+            if (mKeyguardBound) {
+                return;
+            }
+            mKeyguardBound = true;
+        }
+        mKeyguardDelegate.bindService(mContext);
+    }
+
+    @Override
+    public void onSystemUiStarted() {
+        bindKeyguard();
+    }
+
     /** {@inheritDoc} */
     @Override
     public void systemReady() {
-        mKeyguardDelegate = new KeyguardServiceDelegate(mContext,
-                new StateCallback() {
-                    @Override
-                    public void onTrustedChanged() {
-                        mWindowManagerFuncs.notifyKeyguardTrustedChanged();
-                    }
-                });
+        // In normal flow, systemReady is called before other system services are ready.
+        // So it is better not to bind keyguard here.
         mKeyguardDelegate.onSystemReady();
 
         mVrManagerInternal = LocalServices.getService(VrManagerInternal.class);
@@ -7173,7 +7204,6 @@
 
         readCameraLensCoverState();
         updateUiMode();
-        boolean bindKeyguardNow;
         synchronized (mLock) {
             updateOrientationListenerLp();
             mSystemReady = true;
@@ -7183,18 +7213,13 @@
                     updateSettings();
                 }
             });
-
-            bindKeyguardNow = mDeferBindKeyguard;
-            if (bindKeyguardNow) {
-                // systemBooted ran but wasn't able to bind to the Keyguard, we'll do it now.
-                mDeferBindKeyguard = false;
+            // If this happens, for whatever reason, systemReady came later than systemBooted.
+            // And keyguard should be already bound from systemBooted
+            if (mSystemBooted) {
+                mKeyguardDelegate.onBootCompleted();
             }
         }
 
-        if (bindKeyguardNow) {
-            mKeyguardDelegate.bindService(mContext);
-            mKeyguardDelegate.onBootCompleted();
-        }
         mSystemGestures.systemReady();
         mImmersiveModeConfirmation.systemReady();
     }
@@ -7202,30 +7227,25 @@
     /** {@inheritDoc} */
     @Override
     public void systemBooted() {
-        boolean bindKeyguardNow = false;
-        synchronized (mLock) {
-            // Time to bind Keyguard; take care to only bind it once, either here if ready or
-            // in systemReady if not.
-            if (mKeyguardDelegate != null) {
-                bindKeyguardNow = true;
-            } else {
-                // Because mKeyguardDelegate is null, we know that the synchronized block in
-                // systemReady didn't run yet and setting this will actually have an effect.
-                mDeferBindKeyguard = true;
-            }
-        }
-        if (bindKeyguardNow) {
-            mKeyguardDelegate.bindService(mContext);
-            mKeyguardDelegate.onBootCompleted();
-        }
+        bindKeyguard();
         synchronized (mLock) {
             mSystemBooted = true;
+            if (mSystemReady) {
+                mKeyguardDelegate.onBootCompleted();
+            }
         }
         startedWakingUp();
         screenTurningOn(null);
         screenTurnedOn();
     }
 
+    @Override
+    public boolean canDismissBootAnimation() {
+        synchronized (mLock) {
+            return mKeyguardDrawComplete;
+        }
+    }
+
     ProgressDialog mBootMsgDialog = null;
 
     /** {@inheritDoc} */
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index a8d19e9..cf5bfc9 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -1397,13 +1397,16 @@
         try {
             switch (mWakefulness) {
                 case WAKEFULNESS_ASLEEP:
-                    Slog.i(TAG, "Waking up from sleep (uid " + reasonUid +")...");
+                    Slog.i(TAG, "Waking up from sleep (uid=" + reasonUid + " reason=" + reason
+                            + ")...");
                     break;
                 case WAKEFULNESS_DREAMING:
-                    Slog.i(TAG, "Waking up from dream (uid " + reasonUid +")...");
+                    Slog.i(TAG, "Waking up from dream (uid=" + reasonUid + " reason=" + reason
+                            + ")...");
                     break;
                 case WAKEFULNESS_DOZING:
-                    Slog.i(TAG, "Waking up from dozing (uid " + reasonUid +")...");
+                    Slog.i(TAG, "Waking up from dozing (uid=" + reasonUid + " reason=" + reason
+                            + ")...");
                     break;
             }
 
diff --git a/services/core/java/com/android/server/radio/Tuner.java b/services/core/java/com/android/server/radio/Tuner.java
index 0667d41..9915c34 100644
--- a/services/core/java/com/android/server/radio/Tuner.java
+++ b/services/core/java/com/android/server/radio/Tuner.java
@@ -22,6 +22,8 @@
 import android.hardware.radio.RadioManager;
 import android.util.Slog;
 
+import java.util.List;
+
 class Tuner extends ITuner.Stub {
     // TODO(b/36863239): rename to RadioService.Tuner when native service goes away
     private static final String TAG = "RadioServiceJava.Tuner";
@@ -65,6 +67,14 @@
     private native void nativeCancel(long nativeContext);
 
     private native RadioManager.ProgramInfo nativeGetProgramInformation(long nativeContext);
+    private native boolean nativeStartBackgroundScan(long nativeContext);
+    private native List<RadioManager.ProgramInfo> nativeGetProgramList(long nativeContext,
+            String filter);
+
+    private native boolean nativeIsAnalogForced(long nativeContext);
+    private native void nativeSetAnalogForced(long nativeContext, boolean isForced);
+
+    private native boolean nativeIsAntennaConnected(long nativeContext);
 
     @Override
     public void close() {
@@ -168,4 +178,48 @@
             return nativeGetProgramInformation(mNativeContext);
         }
     }
+
+    @Override
+    public boolean startBackgroundScan() {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            return nativeStartBackgroundScan(mNativeContext);
+        }
+    }
+
+    @Override
+    public List<RadioManager.ProgramInfo> getProgramList(String filter) {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            List<RadioManager.ProgramInfo> list = nativeGetProgramList(mNativeContext, filter);
+            if (list == null) {
+                throw new IllegalStateException("Program list is not ready");
+            }
+            return list;
+        }
+    }
+
+    @Override
+    public boolean isAnalogForced() {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            return nativeIsAnalogForced(mNativeContext);
+        }
+    }
+
+    @Override
+    public void setAnalogForced(boolean isForced) {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            nativeSetAnalogForced(mNativeContext, isForced);
+        }
+    }
+
+    @Override
+    public boolean isAntennaConnected() {
+        synchronized (mLock) {
+            checkNotClosedLocked();
+            return nativeIsAntennaConnected(mNativeContext);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/storage/CacheQuotaStrategy.java b/services/core/java/com/android/server/storage/CacheQuotaStrategy.java
index 82dd9ac..7a35bf7 100644
--- a/services/core/java/com/android/server/storage/CacheQuotaStrategy.java
+++ b/services/core/java/com/android/server/storage/CacheQuotaStrategy.java
@@ -177,7 +177,7 @@
             UserInfo info = users.get(i);
             List<UsageStats> stats =
                     mUsageStats.queryUsageStatsForUser(info.id, UsageStatsManager.INTERVAL_BEST,
-                            oneYearAgo, timeNow);
+                            oneYearAgo, timeNow, /*obfuscateInstantApps=*/ false);
             if (stats == null) {
                 continue;
             }
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 377b193..35e4e58 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -830,6 +830,10 @@
             // coalesce refresh messages.
             mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
             mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
+
+            // Make sure handler processes the message before returning, such that isDeviceLocked
+            // after this call will retrieve the correct value.
+            mHandler.runWithScissors(() -> {}, 0);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index fb7ccc7..4044fdb 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -368,7 +368,7 @@
 
             // There is an active service, update it if needed
             updateCurrentVrServiceLocked(mVrModeEnabled, mCurrentVrService.getComponent(),
-                    mCurrentVrService.getUserId(), null);
+                    mCurrentVrService.getUserId(), mCurrentVrModeComponent);
         }
     }
 
@@ -675,7 +675,7 @@
      * @param enabled new state for VR mode.
      * @param component new component to be bound as a VR listener.
      * @param userId user owning the component to be bound.
-     * @param calling the component currently using VR mode, or null to leave unchanged.
+     * @param calling the component currently using VR mode.
      *
      * @return {@code true} if the component/user combination specified is valid.
      */
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdater.java b/services/core/java/com/android/server/webkit/WebViewUpdater.java
index 37479c8..203bbf6 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdater.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdater.java
@@ -68,7 +68,7 @@
     // The WebView package currently in use (or the one we are preparing).
     private PackageInfo mCurrentWebViewPackage = null;
 
-    private Object mLock = new Object();
+    private final Object mLock = new Object();
 
     WebViewUpdater(Context context, SystemInterface systemInterface) {
         mContext = context;
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index 16edd35..65e3ec0 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -411,7 +411,9 @@
         }
 
         if (DEBUG_ANIM) Slog.v(TAG, "Animation done in " + mAppToken
-                + ": reportedVisible=" + mAppToken.reportedVisible);
+                + ": reportedVisible=" + mAppToken.reportedVisible
+                + " okToDisplay=" + mService.okToDisplay()
+                + " startingDisplayed=" + mAppToken.startingDisplayed);
 
         transformation.clear();
 
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index b5e194b..c982f08 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -19,6 +19,7 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
@@ -98,18 +99,27 @@
     private final Runnable mRemoveStartingWindow = () -> {
         StartingSurface surface = null;
         synchronized (mWindowMap) {
+            if (mContainer == null) {
+                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "mContainer was null while trying to"
+                        + " remove starting window");
+                return;
+            }
             if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Remove starting " + mContainer
                     + ": startingWindow=" + mContainer.startingWindow
                     + " startingView=" + mContainer.startingSurface);
-            if (mContainer == null) {
-                return;
-            }
             if (mContainer.startingWindow != null) {
                 surface = mContainer.startingSurface;
                 mContainer.startingData = null;
                 mContainer.startingSurface = null;
                 mContainer.startingWindow = null;
                 mContainer.startingDisplayed = false;
+                if (surface == null && DEBUG_STARTING_WINDOW) {
+                    Slog.v(TAG_WM, "startingWindow was set but startingSurface==null, couldn't "
+                            + "remove");
+                }
+            } else if (DEBUG_STARTING_WINDOW) {
+                Slog.v(TAG_WM, "Tried to remove starting window but startingWindow was null:"
+                        + mContainer);
             }
         }
         if (surface != null) {
@@ -127,6 +137,8 @@
 
         synchronized (mWindowMap) {
             if (mContainer == null) {
+                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "mContainer was null while trying to"
+                        + " add starting window");
                 return;
             }
             startingData = mContainer.startingData;
@@ -135,6 +147,8 @@
 
         if (startingData == null) {
             // Animation has been canceled... do nothing.
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "startingData was nulled out before handling"
+                    + " mAddStartingWindow: " + mContainer);
             return;
         }
 
@@ -174,6 +188,8 @@
             if (abort) {
                 surface.remove();
             }
+        } else if (DEBUG_STARTING_WINDOW) {
+            Slog.v(TAG_WM, "Surface returned was null: " + mContainer);
         }
     };
 
@@ -447,10 +463,12 @@
     public boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
             CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
             IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
-            boolean allowTaskSnapshot) {
+            boolean allowTaskSnapshot, boolean activityCreated) {
         synchronized(mWindowMap) {
             if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "setAppStartingWindow: token=" + mToken
-                    + " pkg=" + pkg + " transferFrom=" + transferFrom);
+                    + " pkg=" + pkg + " transferFrom=" + transferFrom + " newTask=" + newTask
+                    + " taskSwitch=" + taskSwitch + " processRunning=" + processRunning
+                    + " allowTaskSnapshot=" + allowTaskSnapshot);
 
             if (mContainer == null) {
                 Slog.w(TAG_WM, "Attempted to set icon of non-existing app token: " + mToken);
@@ -475,7 +493,7 @@
             }
 
             final int type = getStartingWindowType(newTask, taskSwitch, processRunning,
-                    allowTaskSnapshot);
+                    allowTaskSnapshot, activityCreated);
 
             if (type == STARTING_WINDOW_TYPE_SNAPSHOT) {
                 return createSnapshot();
@@ -536,7 +554,7 @@
                 return false;
             }
 
-            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating StartingData");
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SplashScreenStartingData");
             mContainer.startingData = new SplashScreenStartingData(mService, pkg, theme,
                     compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
                     mContainer.getMergedOverrideConfiguration());
@@ -546,8 +564,9 @@
     }
 
     private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning,
-            boolean allowTaskSnapshot) {
-        if (newTask || !processRunning) {
+            boolean allowTaskSnapshot, boolean activityCreated) {
+        if (newTask || !processRunning
+                || (taskSwitch && !activityCreated)) {
             return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
         } else if (taskSwitch && allowTaskSnapshot) {
             return STARTING_WINDOW_TYPE_SNAPSHOT;
@@ -573,6 +592,7 @@
             return false;
         }
 
+        if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SnapshotStartingData");
         mContainer.startingData = new SnapshotStartingData(mService, snapshot);
         scheduleAddStartingWindow();
         return true;
@@ -582,6 +602,8 @@
         synchronized (mWindowMap) {
             if (mHandler.hasCallbacks(mRemoveStartingWindow)) {
                 // Already scheduled.
+                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Trying to remove starting window but "
+                        + "already scheduled");
                 return;
             }
 
@@ -596,8 +618,7 @@
                 return;
             }
 
-            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, Debug.getCallers(1)
-                    + ": Schedule remove starting " + mContainer
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Schedule remove starting " + mContainer
                     + " startingWindow=" + mContainer.startingWindow);
             mHandler.post(mRemoveStartingWindow);
         }
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 96ea5e5..17db253 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -38,6 +38,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
@@ -53,7 +54,6 @@
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Binder;
-import android.os.Build;
 import android.os.Debug;
 import android.os.IBinder;
 import android.os.SystemClock;
@@ -155,6 +155,9 @@
     StartingSurface startingSurface;
     boolean startingDisplayed;
     boolean startingMoved;
+    // True if the hidden state of this token was forced to false due to a transferred starting
+    // window.
+    private boolean mHiddenSetFromTransferredStartingWindow;
     boolean firstWindowDrawn;
     private final WindowState.UpdateReportedVisibilityResults mReportedVisibilityResults =
             new WindowState.UpdateReportedVisibilityResults();
@@ -185,7 +188,7 @@
     ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();
     ArrayDeque<Configuration> mFrozenMergedConfig = new ArrayDeque<>();
 
-    private boolean mDisbalePreviewScreenshots;
+    private boolean mDisablePreviewScreenshots;
 
     Task mLastParent;
 
@@ -560,6 +563,9 @@
             // with it will be removed as soon as their animations are complete
             mAppAnimator.clearAnimation();
             mAppAnimator.animating = false;
+            if (stack != null) {
+                stack.mExitingAppTokens.remove(this);
+            }
             removeIfPossible();
         }
 
@@ -787,14 +793,22 @@
             if (getController() != null) {
                 getController().removeStartingWindow();
             }
-        } else if (mChildren.size() == 0 && startingData != null) {
+        } else if (mChildren.size() == 0) {
             // If this is the last window and we had requested a starting transition window,
             // well there is no point now.
             if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingData");
             startingData = null;
+            if (mHiddenSetFromTransferredStartingWindow) {
+                // We set the hidden state to false for the token from a transferred starting window.
+                // We now reset it back to true since the starting window was the last window in the
+                // token.
+                hidden = true;
+            }
         } else if (mChildren.size() == 1 && startingSurface != null && !isRelaunching()) {
             // If this is the last window except for a starting transition window,
             // we need to get rid of the starting transition.
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Last window, removing starting window "
+                    + win);
             if (getController() != null) {
                 getController().removeStartingWindow();
             }
@@ -1168,6 +1182,7 @@
                     "Removing starting " + tStartingWindow + " from " + fromToken);
             fromToken.removeChild(tStartingWindow);
             fromToken.postWindowRemoveStartingWindowCleanup(tStartingWindow);
+            fromToken.mHiddenSetFromTransferredStartingWindow = false;
             addWindow(tStartingWindow);
 
             // Propagate other interesting state between the tokens. If the old token is displayed,
@@ -1183,6 +1198,7 @@
             if (!fromToken.hidden) {
                 hidden = false;
                 hiddenRequested = false;
+                mHiddenSetFromTransferredStartingWindow = true;
             }
             setClientHidden(fromToken.mClientHidden);
             fromToken.mAppAnimator.transferCurrentAnimation(
@@ -1359,7 +1375,7 @@
      *         windows in this app token where not considered drawn as of the last pass.
      */
     boolean updateDrawnWindowStates(WindowState w) {
-        if (DEBUG_STARTING_WINDOW && w == startingWindow) {
+        if (DEBUG_STARTING_WINDOW_VERBOSE && w == startingWindow) {
             Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + w.isOnScreen()
                     + " allDrawn=" + allDrawn + " freezingScreen=" + mAppAnimator.freezingScreen);
         }
@@ -1541,7 +1557,7 @@
      * See {@link Activity#setDisablePreviewScreenshots}.
      */
     void setDisablePreviewScreenshots(boolean disable) {
-        mDisbalePreviewScreenshots = disable;
+        mDisablePreviewScreenshots = disable;
     }
 
     /**
@@ -1553,7 +1569,7 @@
      *         screenshot.
      */
     boolean shouldUseAppThemeSnapshot() {
-        return mDisbalePreviewScreenshots || forAllWindows(w -> (w.mAttrs.flags & FLAG_SECURE) != 0,
+        return mDisablePreviewScreenshots || forAllWindows(w -> (w.mAttrs.flags & FLAG_SECURE) != 0,
                 true /* topToBottom */);
     }
 
@@ -1601,11 +1617,13 @@
                     pw.print(" mIsExiting="); pw.println(mIsExiting);
         }
         if (startingWindow != null || startingSurface != null
-                || startingDisplayed || startingMoved) {
+                || startingDisplayed || startingMoved || mHiddenSetFromTransferredStartingWindow) {
             pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
                     pw.print(" startingSurface="); pw.print(startingSurface);
                     pw.print(" startingDisplayed="); pw.print(startingDisplayed);
-                    pw.print(" startingMoved="); pw.println(startingMoved);
+                    pw.print(" startingMoved="); pw.print(startingMoved);
+                    pw.println(" mHiddenSetFromTransferredStartingWindow="
+                            + mHiddenSetFromTransferredStartingWindow);
         }
         if (!mFrozenBounds.isEmpty()) {
             pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 257f285..221e795 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -520,9 +520,16 @@
                 }
                 w.mLayoutNeeded = false;
                 w.prelayout();
+                final boolean firstLayout = !w.isLaidOut();
                 mService.mPolicy.layoutWindowLw(w, null);
                 w.mLayoutSeq = mService.mLayoutSeq;
 
+                // If this is the first layout, we need to initialize the last inset values as
+                // otherwise we'd immediately cause an unnecessary resize.
+                if (firstLayout) {
+                    w.updateLastInsetValues();
+                }
+
                 // Window frames may have changed. Update dim layer with the new bounds.
                 final Task task = w.getTask();
                 if (task != null) {
@@ -1892,6 +1899,11 @@
         return true;
     }
 
+    /** @return 'true' if removal of this display content is deferred due to active animation. */
+    boolean isRemovalDeferred() {
+        return mDeferredRemoval;
+    }
+
     boolean animateForIme(float interpolatedValue, float animationTarget,
             float dividerAnimationTarget) {
         boolean updated = false;
@@ -2891,6 +2903,11 @@
                 * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
         final MutableBoolean mutableIncludeFullDisplay = new MutableBoolean(includeFullDisplay);
         synchronized(mService.mWindowMap) {
+            if (!mService.mPolicy.isScreenOn()) {
+                if (DEBUG_SCREENSHOT) Slog.i(TAG_WM, "Attempted to take screenshot while display"
+                        + " was off.");
+                return null;
+            }
             // Figure out the part of the screen that is actually the app.
             mScreenshotApplicationState.appWin = null;
             forAllWindows(w -> {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index be3558b..233e75b 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -181,7 +181,12 @@
 
         final int size = mChildren.size();
         for (int i = 0; i < size; ++i) {
-            displaysInFocusOrder.put(i, mChildren.get(i).getDisplayId());
+            final DisplayContent displayContent = mChildren.get(i);
+            if (displayContent.isRemovalDeferred()) {
+                // Don't report displays that are going to be removed soon.
+                continue;
+            }
+            displaysInFocusOrder.put(i, displayContent.getDisplayId());
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 6a7123c..091e1cb 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -159,6 +159,7 @@
         }
     }
 
+    @Override
     public void binderDied() {
         // Note: it is safe to call in to the input method manager
         // here because we are not holding our lock.
@@ -205,6 +206,7 @@
             outContentInsets, outStableInsets, null /* outOutsets */, null);
     }
 
+    @Override
     public void remove(IWindow window) {
         mService.removeWindow(this, window);
     }
@@ -214,6 +216,7 @@
         mService.setWillReplaceWindows(appToken, childrenOnly);
     }
 
+    @Override
     public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
             int requestedWidth, int requestedHeight, int viewFlags,
             int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
@@ -230,42 +233,50 @@
         return res;
     }
 
+    @Override
     public boolean outOfMemory(IWindow window) {
         return mService.outOfMemoryWindow(this, window);
     }
 
+    @Override
     public void setTransparentRegion(IWindow window, Region region) {
         mService.setTransparentRegionWindow(this, window, region);
     }
 
+    @Override
     public void setInsets(IWindow window, int touchableInsets,
             Rect contentInsets, Rect visibleInsets, Region touchableArea) {
         mService.setInsetsWindow(this, window, touchableInsets, contentInsets,
                 visibleInsets, touchableArea);
     }
 
+    @Override
     public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
         mService.getWindowDisplayFrame(this, window, outDisplayFrame);
     }
 
+    @Override
     public void finishDrawing(IWindow window) {
         if (WindowManagerService.localLOGV) Slog.v(
             TAG_WM, "IWindow finishDrawing called for " + window);
         mService.finishDrawingWindow(this, window);
     }
 
+    @Override
     public void setInTouchMode(boolean mode) {
         synchronized(mService.mWindowMap) {
             mService.mInTouchMode = mode;
         }
     }
 
+    @Override
     public boolean getInTouchMode() {
         synchronized(mService.mWindowMap) {
             return mService.mInTouchMode;
         }
     }
 
+    @Override
     public boolean performHapticFeedback(IWindow window, int effectId,
             boolean always) {
         synchronized(mService.mWindowMap) {
@@ -281,12 +292,14 @@
     }
 
     /* Drag/drop */
+    @Override
     public IBinder prepareDrag(IWindow window, int flags,
             int width, int height, Surface outSurface) {
         return mService.prepareDragSurface(window, mSurfaceSession, flags,
                 width, height, outSurface);
     }
 
+    @Override
     public boolean performDrag(IWindow window, IBinder dragToken,
             int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY,
             ClipData data) {
@@ -370,6 +383,7 @@
         return true;    // success!
     }
 
+    @Override
     public boolean startMovingTask(IWindow window, float startX, float startY) {
         if (DEBUG_TASK_POSITIONING) Slog.d(
                 TAG_WM, "startMovingTask: {" + startX + "," + startY + "}");
@@ -382,6 +396,7 @@
         }
     }
 
+    @Override
     public void reportDropResult(IWindow window, boolean consumed) {
         IBinder token = window.asBinder();
         if (DEBUG_DRAG) {
@@ -422,6 +437,7 @@
         }
     }
 
+    @Override
     public void cancelDragAndDrop(IBinder dragToken) {
         if (DEBUG_DRAG) {
             Slog.d(TAG_WM, "cancelDragAndDrop");
@@ -450,18 +466,21 @@
         }
     }
 
+    @Override
     public void dragRecipientEntered(IWindow window) {
         if (DEBUG_DRAG) {
             Slog.d(TAG_WM, "Drag into new candidate view @ " + window.asBinder());
         }
     }
 
+    @Override
     public void dragRecipientExited(IWindow window) {
         if (DEBUG_DRAG) {
             Slog.d(TAG_WM, "Drag from old candidate view @ " + window.asBinder());
         }
     }
 
+    @Override
     public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
         synchronized(mService.mWindowMap) {
             long ident = Binder.clearCallingIdentity();
@@ -475,12 +494,14 @@
         }
     }
 
+    @Override
     public void wallpaperOffsetsComplete(IBinder window) {
         synchronized (mService.mWindowMap) {
             mService.mRoot.mWallpaperController.wallpaperOffsetsComplete(window);
         }
     }
 
+    @Override
     public void setWallpaperDisplayOffset(IBinder window, int x, int y) {
         synchronized(mService.mWindowMap) {
             long ident = Binder.clearCallingIdentity();
@@ -493,6 +514,7 @@
         }
     }
 
+    @Override
     public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
             int z, Bundle extras, boolean sync) {
         synchronized(mService.mWindowMap) {
@@ -507,12 +529,14 @@
         }
     }
 
+    @Override
     public void wallpaperCommandComplete(IBinder window, Bundle result) {
         synchronized (mService.mWindowMap) {
             mService.mRoot.mWallpaperController.wallpaperCommandComplete(window);
         }
     }
 
+    @Override
     public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) {
         synchronized(mService.mWindowMap) {
             final long identity = Binder.clearCallingIdentity();
@@ -524,6 +548,7 @@
         }
     }
 
+    @Override
     public IWindowId getWindowId(IBinder window) {
         return mService.getWindowId(window);
     }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 27661e2..818df01 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -41,6 +41,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.PrintWriter;
+import java.util.function.Consumer;
 
 class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerUser {
     static final String TAG = TAG_WITH_CLASS_NAME ? "Task" : TAG_WM;
@@ -684,6 +685,11 @@
     }
 
     @Override
+    void forAllTasks(Consumer<Task> callback) {
+        callback.accept(this);
+    }
+
+    @Override
     public String toString() {
         return "{taskId=" + mTaskId + " appTokens=" + mChildren + " mdr=" + mDeferRemoval + "}";
     }
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 1bbe1d0..24cb464 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -30,8 +30,10 @@
 import android.graphics.GraphicBuffer;
 import android.graphics.Rect;
 import android.os.Environment;
+import android.os.Handler;
 import android.util.ArraySet;
 import android.view.WindowManager.LayoutParams;
+import android.view.WindowManagerPolicy.ScreenOffListener;
 import android.view.WindowManagerPolicy.StartingSurface;
 
 import com.google.android.collect.Sets;
@@ -40,6 +42,7 @@
 import com.android.server.wm.TaskSnapshotSurface.SystemBarBackgroundPainter;
 
 import java.io.PrintWriter;
+import java.util.function.Consumer;
 
 /**
  * When an app token becomes invisible, we take a snapshot (bitmap) of the corresponding task and
@@ -83,6 +86,7 @@
             Environment::getDataSystemCeDirectory);
     private final TaskSnapshotLoader mLoader = new TaskSnapshotLoader(mPersister);
     private final ArraySet<Task> mTmpTasks = new ArraySet<>();
+    private final Handler mHandler = new Handler();
 
     TaskSnapshotController(WindowManagerService service) {
         mService = service;
@@ -114,8 +118,13 @@
         // We need to take a snapshot of the task if and only if all activities of the task are
         // either closing or hidden.
         getClosingTasks(closingApps, mTmpTasks);
-        for (int i = mTmpTasks.size() - 1; i >= 0; i--) {
-            final Task task = mTmpTasks.valueAt(i);
+        snapshotTasks(mTmpTasks);
+
+    }
+
+    private void snapshotTasks(ArraySet<Task> tasks) {
+        for (int i = tasks.size() - 1; i >= 0; i--) {
+            final Task task = tasks.valueAt(i);
             final int mode = getSnapshotMode(task);
             final TaskSnapshot snapshot;
             switch (mode) {
@@ -284,6 +293,33 @@
         mPersister.setPaused(paused);
     }
 
+    /**
+     * Called when screen is being turned off.
+     */
+    void screenTurningOff(ScreenOffListener listener) {
+        if (!ENABLE_TASK_SNAPSHOTS || ActivityManager.isLowRamDeviceStatic()) {
+            listener.onScreenOff();
+            return;
+        }
+
+        // We can't take a snapshot when screen is off, so take a snapshot now!
+        mHandler.post(() -> {
+            try {
+                synchronized (mService.mWindowMap) {
+                    mTmpTasks.clear();
+                    mService.mRoot.forAllTasks(task -> {
+                        if (task.isVisible()) {
+                            mTmpTasks.add(task);
+                        }
+                    });
+                    snapshotTasks(mTmpTasks);
+                }
+            } finally {
+                listener.onScreenOff();
+            }
+        });
+    }
+
     void dump(PrintWriter pw, String prefix) {
         mCache.dump(pw, prefix);
     }
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index 0287070..297e288 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -39,6 +39,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.ArrayDeque;
+import java.util.ArrayList;
 
 /**
  * Persists {@link TaskSnapshot}s to disk.
@@ -55,10 +56,13 @@
     private static final int QUALITY = 95;
     private static final String PROTO_EXTENSION = ".proto";
     private static final String BITMAP_EXTENSION = ".jpg";
+    private static final int MAX_STORE_QUEUE_DEPTH = 2;
 
     @GuardedBy("mLock")
     private final ArrayDeque<WriteQueueItem> mWriteQueue = new ArrayDeque<>();
     @GuardedBy("mLock")
+    private final ArrayDeque<StoreWriteQueueItem> mStoreQueueItems = new ArrayDeque<>();
+    @GuardedBy("mLock")
     private boolean mQueueIdling;
     @GuardedBy("mLock")
     private boolean mPaused;
@@ -153,11 +157,22 @@
     @GuardedBy("mLock")
     private void sendToQueueLocked(WriteQueueItem item) {
         mWriteQueue.offer(item);
+        item.onQueuedLocked();
+        ensureStoreQueueDepthLocked();
         if (!mPaused) {
             mLock.notifyAll();
         }
     }
 
+    @GuardedBy("mLock")
+    private void ensureStoreQueueDepthLocked() {
+        while (mStoreQueueItems.size() > MAX_STORE_QUEUE_DEPTH) {
+            final StoreWriteQueueItem item = mStoreQueueItems.poll();
+            mWriteQueue.remove(item);
+            Slog.i(TAG, "Queue is too deep! Purged item with taskid=" + item.mTaskId);
+        }
+    }
+
     private File getDirectory(int userId) {
         return new File(mDirectoryResolver.getSystemDirectoryForUser(userId), SNAPSHOTS_DIRNAME);
     }
@@ -202,6 +217,9 @@
                         next = null;
                     } else {
                         next = mWriteQueue.poll();
+                        if (next != null) {
+                            next.onDequeuedLocked();
+                        }
                     }
                 }
                 if (next != null) {
@@ -209,11 +227,12 @@
                     SystemClock.sleep(DELAY_MS);
                 }
                 synchronized (mLock) {
-                    if (!mWriteQueue.isEmpty()) {
+                    final boolean writeQueueEmpty = mWriteQueue.isEmpty();
+                    if (!writeQueueEmpty && !mPaused) {
                         continue;
                     }
                     try {
-                        mQueueIdling = true;
+                        mQueueIdling = writeQueueEmpty;
                         mLock.wait();
                         mQueueIdling = false;
                     } catch (InterruptedException e) {
@@ -225,6 +244,18 @@
 
     private abstract class WriteQueueItem {
         abstract void write();
+
+        /**
+         * Called when this queue item has been put into the queue.
+         */
+        void onQueuedLocked() {
+        }
+
+        /**
+         * Called when this queue item has been taken out of the queue.
+         */
+        void onDequeuedLocked() {
+        }
     }
 
     private class StoreWriteQueueItem extends WriteQueueItem {
@@ -239,6 +270,16 @@
         }
 
         @Override
+        void onQueuedLocked() {
+            mStoreQueueItems.offer(this);
+        }
+
+        @Override
+        void onDequeuedLocked() {
+            mStoreQueueItems.remove(this);
+        }
+
+        @Override
         void write() {
             if (!createDirectory(mUserId)) {
                 Slog.e(TAG, "Unable to create snapshot directory for user dir="
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index 2b9e800..3a116bb 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -39,6 +39,7 @@
 import static com.android.internal.policy.DecorView.getColorViewLeftInset;
 import static com.android.internal.policy.DecorView.getColorViewTopInset;
 import static com.android.internal.policy.DecorView.getNavigationBarRect;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
@@ -113,10 +114,9 @@
     private final Rect mStableInsets = new Rect();
     private final Rect mContentInsets = new Rect();
     private final Rect mFrame = new Rect();
-    private final TaskSnapshot mSnapshot;
+    private TaskSnapshot mSnapshot;
     private final CharSequence mTitle;
     private boolean mHasDrawn;
-    private boolean mReportNextDraw;
     private long mShownTime;
     private final Handler mHandler;
     private boolean mSizeMismatch;
@@ -233,10 +233,14 @@
             final long now = SystemClock.uptimeMillis();
             if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS) {
                 mHandler.postAtTime(this::remove, mShownTime + SIZE_MISMATCH_MINIMUM_TIME_MS);
+                if (DEBUG_STARTING_WINDOW) {
+                    Slog.v(TAG, "Defer removing snapshot surface in "  + (now - mShownTime) + "ms");
+                }
                 return;
             }
         }
         try {
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Removing snapshot surface");
             mSession.remove(mWindow);
         } catch (RemoteException e) {
             // Local call.
@@ -255,6 +259,8 @@
 
     private void drawSnapshot() {
         final GraphicBuffer buffer = mSnapshot.getSnapshot();
+        if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Drawing snapshot surface sizeMismatch="
+                + mSizeMismatch);
         if (mSizeMismatch) {
             // The dimensions of the buffer and the window don't match, so attaching the buffer
             // will fail. Better create a child window with the exact dimensions and fill the parent
@@ -263,15 +269,14 @@
         } else {
             drawSizeMatchSnapshot(buffer);
         }
-        final boolean reportNextDraw;
         synchronized (mService.mWindowMap) {
             mShownTime = SystemClock.uptimeMillis();
             mHasDrawn = true;
-            reportNextDraw = mReportNextDraw;
         }
-        if (reportNextDraw) {
-            reportDrawn();
-        }
+        reportDrawn();
+
+        // In case window manager leaks us, make sure we don't retain the snapshot.
+        mSnapshot = null;
     }
 
     private void drawSizeMatchSnapshot(GraphicBuffer buffer) {
@@ -356,9 +361,6 @@
     }
 
     private void reportDrawn() {
-        synchronized (mService.mWindowMap) {
-            mReportNextDraw = false;
-        }
         try {
             mSession.finishDrawing(mWindow);
         } catch (RemoteException e) {
@@ -376,9 +378,6 @@
                     final TaskSnapshotSurface surface = (TaskSnapshotSurface) msg.obj;
                     synchronized (surface.mService.mWindowMap) {
                         hasDrawn = surface.mHasDrawn;
-                        if (!hasDrawn) {
-                            surface.mReportNextDraw = true;
-                        }
                     }
                     if (hasDrawn) {
                         surface.reportDrawn();
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index d64dc0e..d85dd0c 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -52,6 +52,7 @@
 
     /** Is any window animating? */
     private boolean mAnimating;
+    private boolean mLastAnimating;
 
     /** Is any app window animating? */
     boolean mAppWindowAnimating;
@@ -158,7 +159,6 @@
      */
     private void animate(long frameTimeNs) {
         boolean transactionOpen = false;
-        boolean wasAnimating = false;
         try {
             synchronized (mService.mWindowMap) {
                 if (!mInitialized) {
@@ -167,8 +167,7 @@
 
                 mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS;
                 mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE;
-                wasAnimating = mAnimating;
-                setAnimating(false);
+                mAnimating = false;
                 mAppWindowAnimating = false;
                 if (DEBUG_WINDOW_TRACE) {
                     Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
@@ -269,25 +268,22 @@
                 mWindowPlacerLocked.requestTraversal();
             }
 
-            if (mAnimating && !wasAnimating) {
+            if (mAnimating && !mLastAnimating) {
 
                 // Usually app transitions but quite a load onto the system already (with all the
                 // things happening in app), so pause task snapshot persisting to not increase the
                 // load.
                 mService.mTaskSnapshotController.setPersisterPaused(true);
-                if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {
-                    Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "animating", 0);
-                }
+                Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "animating", 0);
             }
-
-            if (!mAnimating && wasAnimating) {
+            if (!mAnimating && mLastAnimating) {
                 mWindowPlacerLocked.requestTraversal();
                 mService.mTaskSnapshotController.setPersisterPaused(false);
-                if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {
-                    Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "animating", 0);
-                }
+                Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "animating", 0);
             }
 
+            mLastAnimating = mAnimating;
+
             if (mRemoveReplacedWindows) {
                 mService.mRoot.removeReplacedWindows();
                 mRemoveReplacedWindows = false;
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 84ba139..600bc5c 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -16,6 +16,11 @@
 
 package com.android.server.wm;
 
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.content.res.Configuration.EMPTY;
+
 import android.annotation.CallSuper;
 import android.content.res.Configuration;
 import android.util.Pools;
@@ -27,11 +32,6 @@
 import java.util.function.Consumer;
 import java.util.function.Predicate;
 
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static android.content.res.Configuration.EMPTY;
-
 /**
  * Defines common functionality for classes that can hold windows directly or through their
  * children in a hierarchy form.
@@ -52,7 +52,7 @@
 
     // List of children for this window container. List is in z-order as the children appear on
     // screen with the top-most window container at the tail of the list.
-    protected final LinkedList<E> mChildren = new LinkedList();
+    protected final WindowList<E> mChildren = new WindowList<E>();
 
     /** Contains override configuration settings applied to this window container. */
     private Configuration mOverrideConfiguration = new Configuration();
@@ -258,7 +258,7 @@
             case POSITION_TOP:
                 if (mChildren.peekLast() != child) {
                     mChildren.remove(child);
-                    mChildren.addLast(child);
+                    mChildren.add(child);
                 }
                 if (includingParents && getParent() != null) {
                     getParent().positionChildAt(POSITION_TOP, this /* child */,
@@ -627,6 +627,17 @@
         wrapper.release();
     }
 
+    /**
+     * For all tasks at or below this container call the callback.
+     *
+     * @param callback Callback to be called for every task.
+     */
+    void forAllTasks(Consumer<Task> callback) {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            mChildren.get(i).forAllTasks(callback);
+        }
+    }
+
     WindowState getWindow(Predicate<WindowState> callback) {
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final WindowState w = mChildren.get(i).getWindow(callback);
@@ -649,45 +660,50 @@
         }
 
         if (mParent != null && mParent == other.mParent) {
-            final LinkedList<WindowContainer> list = mParent.mChildren;
+            final WindowList<WindowContainer> list = mParent.mChildren;
             return list.indexOf(this) > list.indexOf(other) ? 1 : -1;
         }
 
         final LinkedList<WindowContainer> thisParentChain = mTmpChain1;
         final LinkedList<WindowContainer> otherParentChain = mTmpChain2;
-        getParents(thisParentChain);
-        other.getParents(otherParentChain);
+        try {
+            getParents(thisParentChain);
+            other.getParents(otherParentChain);
 
-        // Find the common ancestor of both containers.
-        WindowContainer commonAncestor = null;
-        WindowContainer thisTop = thisParentChain.peekLast();
-        WindowContainer otherTop = otherParentChain.peekLast();
-        while (thisTop != null && otherTop != null && thisTop == otherTop) {
-            commonAncestor = thisParentChain.removeLast();
-            otherParentChain.removeLast();
-            thisTop = thisParentChain.peekLast();
-            otherTop = otherParentChain.peekLast();
+            // Find the common ancestor of both containers.
+            WindowContainer commonAncestor = null;
+            WindowContainer thisTop = thisParentChain.peekLast();
+            WindowContainer otherTop = otherParentChain.peekLast();
+            while (thisTop != null && otherTop != null && thisTop == otherTop) {
+                commonAncestor = thisParentChain.removeLast();
+                otherParentChain.removeLast();
+                thisTop = thisParentChain.peekLast();
+                otherTop = otherParentChain.peekLast();
+            }
+
+            // Containers don't belong to the same hierarchy???
+            if (commonAncestor == null) {
+                throw new IllegalArgumentException("No in the same hierarchy this="
+                        + thisParentChain + " other=" + otherParentChain);
+            }
+
+            // Children are always considered greater than their parents, so if one of the containers
+            // we are comparing it the parent of the other then whichever is the child is greater.
+            if (commonAncestor == this) {
+                return -1;
+            } else if (commonAncestor == other) {
+                return 1;
+            }
+
+            // The position of the first non-common ancestor in the common ancestor list determines
+            // which is greater the which.
+            final WindowList<WindowContainer> list = commonAncestor.mChildren;
+            return list.indexOf(thisParentChain.peekLast()) > list.indexOf(otherParentChain.peekLast())
+                    ? 1 : -1;
+        } finally {
+            mTmpChain1.clear();
+            mTmpChain2.clear();
         }
-
-        // Containers don't belong to the same hierarchy???
-        if (commonAncestor == null) {
-            throw new IllegalArgumentException("No in the same hierarchy this="
-                    + thisParentChain + " other=" + otherParentChain);
-        }
-
-        // Children are always considered greater than their parents, so if one of the containers
-        // we are comparing it the parent of the other then whichever is the child is greater.
-        if (commonAncestor == this) {
-            return -1;
-        } else if (commonAncestor == other) {
-            return 1;
-        }
-
-        // The position of the first non-common ancestor in the common ancestor list determines
-        // which is greater the which.
-        final LinkedList<WindowContainer> list = commonAncestor.mChildren;
-        return list.indexOf(thisParentChain.peekLast()) > list.indexOf(otherParentChain.peekLast())
-                ? 1 : -1;
     }
 
     private void getParents(LinkedList<WindowContainer> parents) {
diff --git a/services/core/java/com/android/server/wm/WindowList.java b/services/core/java/com/android/server/wm/WindowList.java
new file mode 100644
index 0000000..dfeba40
--- /dev/null
+++ b/services/core/java/com/android/server/wm/WindowList.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 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
+ */
+
+package com.android.server.wm;
+
+import java.util.ArrayList;
+
+/**
+ * An {@link ArrayList} with extended functionality to be used as the children data structure in
+ * {@link WindowContainer}.
+ */
+class WindowList<E> extends ArrayList<E> {
+
+    void addFirst(E e) {
+        add(0, e);
+    }
+
+    E peekLast() {
+        return size() > 0 ? get(size() - 1) : null;
+    }
+
+    E peekFirst() {
+        return size() > 0 ? get(0) : null;
+    }
+}
diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
index 1b61fca..8279b51 100644
--- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
+++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
@@ -51,7 +51,8 @@
     static final boolean DEBUG_APP_ORIENTATION = false;
     static final boolean DEBUG_CONFIGURATION = false;
     static final boolean DEBUG_APP_TRANSITIONS = false;
-    static final boolean DEBUG_STARTING_WINDOW = false;
+    static final boolean DEBUG_STARTING_WINDOW_VERBOSE = false;
+    static final boolean DEBUG_STARTING_WINDOW = DEBUG_STARTING_WINDOW_VERBOSE || true;
     static final boolean DEBUG_WALLPAPER = false;
     static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER;
     static final boolean DEBUG_DRAG = false;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 54bfeb5..a15891b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -203,6 +203,7 @@
 import android.view.WindowManagerInternal;
 import android.view.WindowManagerPolicy;
 import android.view.WindowManagerPolicy.PointerEventListener;
+import android.view.WindowManagerPolicy.ScreenOffListener;
 import android.view.animation.Animation;
 import android.view.inputmethod.InputMethodManagerInternal;
 
@@ -1521,7 +1522,7 @@
         // Try using the target SDK of the root window
         if (attachedWindow != null) {
             return attachedWindow.mAppToken != null
-                    && attachedWindow.mAppToken.mTargetSdk > Build.VERSION_CODES.N_MR1;
+                    && attachedWindow.mAppToken.mTargetSdk >= Build.VERSION_CODES.O;
         } else {
             // Otherwise, look at the package
             try {
@@ -1532,7 +1533,7 @@
                     throw new SecurityException("Package " + packageName + " not in UID "
                             + callingUid);
                 }
-                if (appInfo.targetSdkVersion > Build.VERSION_CODES.N_MR1) {
+                if (appInfo.targetSdkVersion >= Build.VERSION_CODES.O) {
                     return true;
                 }
             } catch (PackageManager.NameNotFoundException e) {
@@ -1685,6 +1686,10 @@
                 // re-factor.
                 atoken.firstWindowDrawn = false;
                 atoken.clearAllDrawn();
+                final TaskStack stack = atoken.getStack();
+                if (stack != null) {
+                    stack.mExitingAppTokens.remove(atoken);
+                }
             }
         }
 
@@ -2806,6 +2811,11 @@
         mH.sendEmptyMessage(H.NOTIFY_KEYGUARD_TRUSTED_CHANGED);
     }
 
+    @Override
+    public void screenTurningOff(ScreenOffListener listener) {
+        mTaskSnapshotController.screenTurningOff(listener);
+    }
+
     /**
      * Starts deferring layout passes. Useful when doing multiple changes but to optimize
      * performance, only one layout pass should be done. This can be called multiple times, and
@@ -3331,6 +3341,13 @@
         performEnableScreen();
     }
 
+    /**
+     * Called when System UI has been started.
+     */
+    public void onSystemUiStarted() {
+        mPolicy.onSystemUiStarted();
+    }
+
     private void performEnableScreen() {
         synchronized(mWindowMap) {
             if (DEBUG_BOOT) Slog.i(TAG_WM, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
@@ -3346,6 +3363,10 @@
                 return;
             }
 
+            if (!mShowingBootMessages && !mPolicy.canDismissBootAnimation()) {
+                return;
+            }
+
             // Don't enable the screen until all existing windows have been drawn.
             if (!mForceDisplayEnabled
                     // TODO(multidisplay): Expand to all displays?
@@ -3359,7 +3380,7 @@
                 try {
                     IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
                     if (surfaceFlinger != null) {
-                        //Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
+                        Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
                         Parcel data = Parcel.obtain();
                         data.writeInterfaceToken("android.ui.ISurfaceComposer");
                         surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 8c8f633..2ffa152 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -80,6 +80,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
@@ -138,6 +139,7 @@
 import com.android.server.input.InputWindowHandle;
 
 import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.LinkedList;
@@ -170,7 +172,7 @@
     final int mOwnerUid;
     /** The owner has {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW} */
     final boolean mOwnerCanAddInternalSystemWindow;
-    final IWindowId mWindowId;
+    final WindowId mWindowId;
     WindowToken mToken;
     // The same object as mToken if this is an app window and null for non-app windows.
     AppWindowToken mAppToken;
@@ -208,7 +210,7 @@
     boolean mHidden;    // Used to determine if to show child windows.
     boolean mWallpaperVisible;  // for wallpaper, what was last vis report?
     private boolean mDragResizing;
-    private boolean mDragResizingChangeReported;
+    private boolean mDragResizingChangeReported = true;
     private int mResizeMode;
 
     private RemoteCallbackList<IWindowFocusObserver> mFocusCallbacks;
@@ -587,20 +589,7 @@
         mAppToken = mToken.asAppWindowToken();
         mOwnerUid = ownerId;
         mOwnerCanAddInternalSystemWindow = ownerCanAddInternalSystemWindow;
-        mWindowId = new IWindowId.Stub() {
-            @Override
-            public void registerFocusObserver(IWindowFocusObserver observer) {
-                WindowState.this.registerFocusObserver(observer);
-            }
-            @Override
-            public void unregisterFocusObserver(IWindowFocusObserver observer) {
-                WindowState.this.unregisterFocusObserver(observer);
-            }
-            @Override
-            public boolean isFocused() {
-                return WindowState.this.isFocused();
-            }
-        };
+        mWindowId = new WindowId(this);
         mAttrs.copyFrom(a);
         mViewVisibility = viewVisibility;
         mPolicy = mService.mPolicy;
@@ -1155,11 +1144,7 @@
                 return;
             }
 
-            mLastOverscanInsets.set(mOverscanInsets);
-            mLastContentInsets.set(mContentInsets);
-            mLastVisibleInsets.set(mVisibleInsets);
-            mLastStableInsets.set(mStableInsets);
-            mLastOutsets.set(mOutsets);
+            updateLastInsetValues();
             mService.makeWindowFreezingScreenIfNeededLocked(this);
 
             // If the orientation is changing, or we're starting or ending a drag resizing action,
@@ -1310,7 +1295,7 @@
      *         otherwise.
      */
     boolean wouldBeVisibleIfPolicyIgnored() {
-        return mHasSurface && mPolicyVisibility && !isParentWindowHidden()
+        return mHasSurface && !isParentWindowHidden()
                 && !mAnimatingExit && !mDestroying && (!mIsWallpaper || mWallpaperVisible);
     }
 
@@ -3801,7 +3786,7 @@
 
     private void logPerformShow(String prefix) {
         if (DEBUG_VISIBILITY
-                || (DEBUG_STARTING_WINDOW && mAttrs.type == TYPE_APPLICATION_STARTING)) {
+                || (DEBUG_STARTING_WINDOW_VERBOSE && mAttrs.type == TYPE_APPLICATION_STARTING)) {
             Slog.v(TAG, prefix + this
                     + ": mDrawState=" + mWinAnimator.drawStateToString()
                     + " readyForDisplay=" + isReadyForDisplay()
@@ -4404,6 +4389,24 @@
         return result;
     }
 
+    /**
+     * @return True if this window has been laid out at least once; false otherwise.
+     */
+    boolean isLaidOut() {
+        return mLayoutSeq != -1;
+    }
+
+    /**
+     * Updates the last inset values to the current ones.
+     */
+    void updateLastInsetValues() {
+        mLastOverscanInsets.set(mOverscanInsets);
+        mLastContentInsets.set(mContentInsets);
+        mLastVisibleInsets.set(mVisibleInsets);
+        mLastStableInsets.set(mStableInsets);
+        mLastOutsets.set(mOutsets);
+    }
+
     // TODO: Hack to work around the number of states AppWindowToken needs to access without having
     // access to its windows children. Need to investigate re-writing
     // {@link AppWindowToken#updateReportedVisibilityLocked} so this can be removed.
@@ -4421,6 +4424,40 @@
         }
     }
 
+    private static final class WindowId extends IWindowId.Stub {
+        private final WeakReference<WindowState> mOuter;
+
+        private WindowId(WindowState outer) {
+
+            // Use a weak reference for the outer class. This is important to prevent the following
+            // leak: Since we send this class to the client process, binder will keep it alive as
+            // long as the client keeps it alive. Now, if the window is removed, we need to clear
+            // out our reference so even though this class is kept alive we don't leak WindowState,
+            // which can keep a whole lot of classes alive.
+            mOuter = new WeakReference<>(outer);
+        }
+
+        @Override
+        public void registerFocusObserver(IWindowFocusObserver observer) {
+            final WindowState outer = mOuter.get();
+            if (outer != null) {
+                outer.registerFocusObserver(observer);
+            }
+        }
+        @Override
+        public void unregisterFocusObserver(IWindowFocusObserver observer) {
+            final WindowState outer = mOuter.get();
+            if (outer != null) {
+                outer.unregisterFocusObserver(observer);
+            }
+        }
+        @Override
+        public boolean isFocused() {
+            final WindowState outer = mOuter.get();
+            return outer != null && outer.isFocused();
+        }
+    }
+
     boolean usesRelativeZOrdering() {
         if (!isChildWindow()) {
             return false;
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 8d3ef40..d75afcf 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -30,6 +30,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
@@ -519,7 +520,7 @@
 
     // This must be called while inside a transaction.
     boolean commitFinishDrawingLocked() {
-        if (DEBUG_STARTING_WINDOW &&
+        if (DEBUG_STARTING_WINDOW_VERBOSE &&
                 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
             Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
                     + drawStateToString());
@@ -968,10 +969,8 @@
                 tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
             }
 
-            //TODO (multidisplay): Magnification is supported only for the default display.
-            if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) {
-                MagnificationSpec spec = mService.mAccessibilityController
-                        .getMagnificationSpecForWindowLocked(mWin);
+            MagnificationSpec spec = getMagnificationSpec();
+            if (spec != null) {
                 applyMagnificationSpec(spec, tmpMatrix);
             }
 
@@ -1058,11 +1057,7 @@
                 TAG, "computeShownFrameLocked: " + this +
                 " not attached, mAlpha=" + mAlpha);
 
-        MagnificationSpec spec = null;
-        //TODO (multidisplay): Magnification is supported only for the default display.
-        if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) {
-            spec = mService.mAccessibilityController.getMagnificationSpecForWindowLocked(mWin);
-        }
+        MagnificationSpec spec = getMagnificationSpec();
         if (spec != null) {
             final Rect frame = mWin.mFrame;
             final float tmpFloats[] = mService.mTmpFloats;
@@ -1099,6 +1094,14 @@
         }
     }
 
+    private MagnificationSpec getMagnificationSpec() {
+        //TODO (multidisplay): Magnification is supported only for the default display.
+        if (mService.mAccessibilityController != null && mWin.getDisplayId() == DEFAULT_DISPLAY) {
+            return mService.mAccessibilityController.getMagnificationSpecForWindowLocked(mWin);
+        }
+        return null;
+    }
+
     /**
      * In some scenarios we use a screen space clip rect (so called, final clip rect)
      * to crop to stack bounds. Generally because it's easier to deal with while
@@ -1136,6 +1139,27 @@
         if (StackId.tasksAreFloating(stack.mStackId)) {
             w.expandForSurfaceInsets(finalClipRect);
         }
+
+        // We may be applying a magnification spec to all windows,
+        // simulating a transformation in screen space, in which case
+        // we need to transform all other screen space values...including
+        // the final crop. This is kind of messed up and we should look
+        // in to actually transforming screen-space via a parent-layer.
+        // b/38322835
+        MagnificationSpec spec = getMagnificationSpec();
+        if (spec != null && !spec.isNop()) {
+            Matrix transform = mWin.mTmpMatrix;
+            RectF finalCrop = mService.mTmpRectF;
+            transform.reset();
+            transform.postScale(spec.scale, spec.scale);
+            transform.postTranslate(-spec.offsetX, -spec.offsetY);
+            transform.mapRect(finalCrop);
+            finalClipRect.top = (int)finalCrop.top;
+            finalClipRect.left = (int)finalCrop.left;
+            finalClipRect.right = (int)finalClipRect.right;
+            finalClipRect.bottom = (int)finalClipRect.bottom;
+        }
+
         return true;
     }
 
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index 675b641..e6c2b1d 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -10,6 +10,7 @@
     $(LOCAL_REL_DIR)/com_android_server_AlarmManagerService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_am_BatteryStatsService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_connectivity_Vpn.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_connectivity_tethering_OffloadHardwareInterface.cpp \
     $(LOCAL_REL_DIR)/com_android_server_ConsumerIrService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_HardwarePropertiesManagerService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_hdmi_HdmiCecController.cpp \
@@ -63,6 +64,7 @@
     liblog \
     libhardware \
     libhardware_legacy \
+    libhidlbase \
     libkeystore_binder \
     libnativehelper \
     libutils \
@@ -93,7 +95,7 @@
     android.hardware.ir@1.0 \
     android.hardware.light@2.0 \
     android.hardware.power@1.0 \
-    android.hardware.power@1.1 \
+    android.hardware.tetheroffload.config@1.0 \
     android.hardware.thermal@1.0 \
     android.hardware.tv.cec@1.0 \
     android.hardware.tv.input@1.0 \
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
index 37ae782..57bb9fe 100644
--- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -29,7 +29,6 @@
 #include <unistd.h>
 
 #include <android/hardware/power/1.0/IPower.h>
-#include <android/hardware/power/1.1/IPower.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <jni.h>
 
@@ -47,8 +46,6 @@
 using android::hardware::power::V1_0::PowerStatePlatformSleepState;
 using android::hardware::power::V1_0::PowerStateVoter;
 using android::hardware::power::V1_0::Status;
-using android::hardware::power::V1_1::PowerStateSubsystem;
-using android::hardware::power::V1_1::PowerStateSubsystemSleepState;
 using android::hardware::hidl_vec;
 
 namespace android
@@ -266,105 +263,9 @@
     return total_added;
 }
 
-static jint getSubsystemLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject outBuf) {
-    char *output = (char*)env->GetDirectBufferAddress(outBuf);
-    char *offset = output;
-    int remaining = (int)env->GetDirectBufferCapacity(outBuf);
-    int total_added = -1;
-
-	//This is a IPower 1.1 API
-    sp<android::hardware::power::V1_1::IPower> gPowerHal_1_1 = nullptr;
-
-    if (outBuf == NULL) {
-        jniThrowException(env, "java/lang/NullPointerException", "null argument");
-        return -1;
-    }
-
-    {
-        std::lock_guard<std::mutex> lock(gPowerHalMutex);
-        if (!getPowerHal()) {
-            ALOGE("Power Hal not loaded");
-            return -1;
-        }
-
-        //Trying to cast to 1.1, this will succeed only for devices supporting 1.1
-        gPowerHal_1_1 = android::hardware::power::V1_1::IPower::castFrom(gPowerHal);
-    	if (gPowerHal_1_1 == nullptr) {
-            //This device does not support IPower@1.1, exiting gracefully
-            return 0;
-    	}
-
-        Return<void> ret = gPowerHal_1_1->getSubsystemLowPowerStats(
-           [&offset, &remaining, &total_added](hidl_vec<PowerStateSubsystem> subsystems,
-                Status status) {
-
-            if (status != Status::SUCCESS)
-                return;
-
-            for (size_t i = 0; i < subsystems.size(); i++) {
-                int added;
-                const PowerStateSubsystem &subsystem = subsystems[i];
-
-                added = snprintf(offset, remaining,
-                                 "subsystem_%zu name=%s ", i + 1, subsystem.name.c_str());
-                if (added < 0) {
-                    break;
-                }
-
-                if (added > remaining) {
-                    added = remaining;
-                }
-
-                offset += added;
-                remaining -= added;
-                total_added += added;
-
-                for (size_t j = 0; j < subsystem.states.size(); j++) {
-                    const PowerStateSubsystemSleepState& state = subsystem.states[j];
-                    added = snprintf(offset, remaining,
-                                     "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " last entry TS(ms)=%" PRIu64 " ",
-                                     j + 1, state.name.c_str(), state.residencyInMsecSinceBoot,
-                                     state.totalTransitions, state.lastEntryTimestampMs);
-                    if (added < 0) {
-                        break;
-                    }
-
-                    if (added > remaining) {
-                        added = remaining;
-                    }
-
-                    offset += added;
-                    remaining -= added;
-                    total_added += added;
-                }
-
-                if (remaining <= 0) {
-                    /* rewrite NULL character*/
-                    offset--;
-                    total_added--;
-                    ALOGE("PowerHal: buffer not enough");
-                    break;
-                }
-            }
-        }
-        );
-
-        if (!ret.isOk()) {
-            ALOGE("getSubsystemLowPowerStats() failed: power HAL service not available");
-            gPowerHal = nullptr;
-            return -1;
-        }
-    }
-
-    *offset = 0;
-    total_added += 1;
-    return total_added;
-}
-
 static const JNINativeMethod method_table[] = {
     { "nativeWaitWakeup", "(Ljava/nio/ByteBuffer;)I", (void*)nativeWaitWakeup },
     { "getPlatformLowPowerStats", "(Ljava/nio/ByteBuffer;)I", (void*)getPlatformLowPowerStats },
-    { "getSubsystemLowPowerStats", "(Ljava/nio/ByteBuffer;)I", (void*)getSubsystemLowPowerStats },
 };
 
 int register_android_server_BatteryStatsService(JNIEnv *env)
diff --git a/services/core/jni/com_android_server_connectivity_tethering_OffloadHardwareInterface.cpp b/services/core/jni/com_android_server_connectivity_tethering_OffloadHardwareInterface.cpp
new file mode 100644
index 0000000..241ccf6
--- /dev/null
+++ b/services/core/jni/com_android_server_connectivity_tethering_OffloadHardwareInterface.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 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 <errno.h>
+#include <error.h>
+#include <hidl/HidlSupport.h>
+#include <jni.h>
+#include <JNIHelp.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netlink.h>
+#include <sys/socket.h>
+#include <android-base/unique_fd.h>
+#include <android/hardware/tetheroffload/config/1.0/IOffloadConfig.h>
+
+#define LOG_TAG "OffloadHardwareInterface"
+#include <utils/Log.h>
+
+namespace android {
+
+using hardware::hidl_handle;
+using hardware::hidl_string;
+using hardware::tetheroffload::config::V1_0::IOffloadConfig;
+
+namespace {
+
+inline const sockaddr * asSockaddr(const sockaddr_nl *nladdr) {
+    return reinterpret_cast<const sockaddr *>(nladdr);
+}
+
+int conntrackSocket(unsigned groups) {
+    base::unique_fd s(socket(AF_NETLINK, SOCK_DGRAM, NETLINK_NETFILTER));
+    if (s.get() < 0) return -errno;
+
+    const struct sockaddr_nl bind_addr = {
+        .nl_family = AF_NETLINK,
+        .nl_pad = 0,
+        .nl_pid = 0,
+        .nl_groups = groups,
+    };
+    if (bind(s.get(), asSockaddr(&bind_addr), sizeof(bind_addr)) != 0) {
+        return -errno;
+    }
+
+    const struct sockaddr_nl kernel_addr = {
+        .nl_family = AF_NETLINK,
+        .nl_pad = 0,
+        .nl_pid = 0,
+        .nl_groups = groups,
+    };
+    if (connect(s.get(), asSockaddr(&kernel_addr), sizeof(kernel_addr)) != 0) {
+        return -errno;
+    }
+
+    return s.release();
+}
+
+// Return a hidl_handle that owns the file descriptor owned by fd, and will
+// auto-close it (otherwise there would be double-close problems).
+//
+// Rely upon the compiler to eliminate the constexprs used for clarity.
+hidl_handle&& handleFromFileDescriptor(base::unique_fd fd) {
+    hidl_handle h;
+
+    NATIVE_HANDLE_DECLARE_STORAGE(storage, 0, 0);
+    static constexpr int kNumFds = 1;
+    static constexpr int kNumInts = 0;
+    native_handle_t *nh = native_handle_init(storage, kNumFds, kNumInts);
+    nh->data[0] = fd.release();
+
+    static constexpr bool kTakeOwnership = true;
+    h.setTo(nh, kTakeOwnership);
+
+    return std::move(h);
+}
+
+}  // namespace
+
+static jboolean android_server_connectivity_tethering_OffloadHardwareInterface_configOffload(
+        JNIEnv* /* env */) {
+    sp<IOffloadConfig> configInterface = IOffloadConfig::getService();
+    if (configInterface.get() == nullptr) {
+        ALOGD("Could not find IOffloadConfig service.");
+        return false;
+    }
+
+    // Per the IConfigOffload definition:
+    //
+    // fd1   A file descriptor bound to the following netlink groups
+    //       (NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY).
+    //
+    // fd2   A file descriptor bound to the following netlink groups
+    //       (NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY).
+    base::unique_fd
+            fd1(conntrackSocket(NFNLGRP_CONNTRACK_NEW | NFNLGRP_CONNTRACK_DESTROY)),
+            fd2(conntrackSocket(NFNLGRP_CONNTRACK_UPDATE | NFNLGRP_CONNTRACK_DESTROY));
+    if (fd1.get() < 0 || fd2.get() < 0) {
+        ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+        return false;
+    }
+
+    hidl_handle h1(handleFromFileDescriptor(std::move(fd1))),
+                h2(handleFromFileDescriptor(std::move(fd2)));
+
+    bool rval;
+    hidl_string msg;
+    configInterface->setHandles(h1, h2,
+            [&rval, &msg](bool success, const hidl_string& errMsg) {
+                rval = success;
+                msg = errMsg;
+            });
+    if (!rval) {
+        ALOGE("IOffloadConfig::setHandles() error: %s", msg.c_str());
+    }
+
+    return rval;
+}
+
+/*
+ * JNI registration.
+ */
+static const JNINativeMethod gMethods[] = {
+    /* name, signature, funcPtr */
+    { "configOffload", "()Z",
+      (void*) android_server_connectivity_tethering_OffloadHardwareInterface_configOffload },
+};
+
+int register_android_server_connectivity_tethering_OffloadHardwareInterface(JNIEnv* env) {
+    return jniRegisterNativeMethods(env,
+            "com/android/server/connectivity/tethering/OffloadHardwareInterface",
+            gMethods, NELEM(gMethods));
+}
+
+}; // namespace android
diff --git a/services/core/jni/com_android_server_radio_RadioService.cpp b/services/core/jni/com_android_server_radio_RadioService.cpp
index ad5d5ee..73887bb 100644
--- a/services/core/jni/com_android_server_radio_RadioService.cpp
+++ b/services/core/jni/com_android_server_radio_RadioService.cpp
@@ -54,10 +54,6 @@
         jclass clazz;
         jmethodID cstor;
     } Tuner;
-
-    struct {
-        jclass clazz;
-    } RadioService;
 } gjni;
 
 struct ServiceContext {
@@ -204,9 +200,6 @@
     gjni.Tuner.cstor = GetMethodIDOrDie(env, tunerClass, "<init>",
             "(Landroid/hardware/radio/ITunerCallback;IIZ)V");
 
-    auto serviceClass = FindClassOrDie(env, "com/android/server/radio/RadioService");
-    gjni.RadioService.clazz = MakeGlobalRefOrDie(env, serviceClass);
-
     auto res = jniRegisterNativeMethods(env, "com/android/server/radio/RadioService",
             gRadioServiceMethods, NELEM(gRadioServiceMethods));
     LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
diff --git a/services/core/jni/com_android_server_radio_Tuner.cpp b/services/core/jni/com_android_server_radio_Tuner.cpp
index a15f4a7..b92136a 100644
--- a/services/core/jni/com_android_server_radio_Tuner.cpp
+++ b/services/core/jni/com_android_server_radio_Tuner.cpp
@@ -48,6 +48,11 @@
 
 static struct {
     struct {
+        jclass clazz;
+        jmethodID cstor;
+        jmethodID add;
+    } ArrayList;
+    struct {
         jfieldID nativeContext;
         jfieldID region;
         jfieldID tunerCallback;
@@ -213,26 +218,120 @@
     auto halTuner11 = getHalTuner11(nativeContext);
     if (halTuner10 == nullptr) return nullptr;
 
-    V1_1::ProgramInfo halInfo;
+    JavaRef<jobject> jInfo;
     Result halResult;
     Return<void> hidlResult;
     if (halTuner11 != nullptr) {
         hidlResult = halTuner11->getProgramInformation_1_1([&](Result result,
                 const V1_1::ProgramInfo& info) {
             halResult = result;
-            halInfo = info;
+            if (result != Result::OK) return;
+            jInfo = convert::ProgramInfoFromHal(env, info);
         });
     } else {
         hidlResult = halTuner10->getProgramInformation([&](Result result,
                 const V1_0::ProgramInfo& info) {
             halResult = result;
-            halInfo.base = info;
+            if (result != Result::OK) return;
+            jInfo = convert::ProgramInfoFromHal(env, info);
         });
     }
 
+    if (jInfo != nullptr) return jInfo.release();
+    convert::ThrowIfFailed(env, hidlResult, halResult);
+    return nullptr;
+}
+
+static bool nativeStartBackgroundScan(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeStartBackgroundScan()");
+    auto halTuner = getHalTuner11(nativeContext);
+    if (halTuner == nullptr) {
+        ALOGI("Background scan is not supported with HAL < 1.1");
+        return false;
+    }
+
+    auto halResult = halTuner->startBackgroundScan();
+
+    if (halResult.isOk() && halResult == ProgramListResult::UNAVAILABLE) return false;
+    return !convert::ThrowIfFailed(env, halResult);
+}
+
+static jobject nativeGetProgramList(JNIEnv *env, jobject obj, jlong nativeContext, jstring jFilter) {
+    ALOGV("nativeGetProgramList()");
+    EnvWrapper wrap(env);
+    auto halTuner = getHalTuner11(nativeContext);
+    if (halTuner == nullptr) {
+        ALOGI("Program list is not supported with HAL < 1.1");
+        return nullptr;
+    }
+
+    JavaRef<jobject> jList;
+    ProgramListResult halResult = ProgramListResult::NOT_INITIALIZED;
+    auto filter = env->GetStringUTFChars(jFilter, nullptr);
+    auto hidlResult = halTuner->getProgramList(filter,
+            [&](ProgramListResult result, const hidl_vec<V1_1::ProgramInfo>& programList) {
+        halResult = result;
+        if (halResult != ProgramListResult::OK) return;
+
+        jList = wrap(env->NewObject(gjni.ArrayList.clazz, gjni.ArrayList.cstor));
+        for (auto& program : programList) {
+            auto jProgram = convert::ProgramInfoFromHal(env, program);
+            env->CallBooleanMethod(jList.get(), gjni.ArrayList.add, jProgram.get());
+        }
+    });
+
     if (convert::ThrowIfFailed(env, hidlResult, halResult)) return nullptr;
 
-    return convert::ProgramInfoFromHal(env, halInfo).release();
+    return jList.release();
+}
+
+static bool nativeIsAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeIsAnalogForced()");
+    auto halTuner = getHalTuner11(nativeContext);
+    if (halTuner == nullptr) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Forced analog switch is not supported with HAL < 1.1");
+        return false;
+    }
+
+    bool isForced;
+    Result halResult;
+    auto hidlResult = halTuner->isAnalogForced([&](Result result, bool isForcedRet) {
+        halResult = result;
+        isForced = isForcedRet;
+    });
+
+    if (convert::ThrowIfFailed(env, hidlResult, halResult)) return false;
+
+    return isForced;
+}
+
+static void nativeSetAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext, bool isForced) {
+    ALOGV("nativeSetAnalogForced()");
+    auto halTuner = getHalTuner11(nativeContext);
+    if (halTuner == nullptr) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Forced analog switch is not supported with HAL < 1.1");
+        return;
+    }
+
+    auto halResult = halTuner->setAnalogForced(isForced);
+    convert::ThrowIfFailed(env, halResult);
+}
+
+static bool nativeIsAntennaConnected(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeIsAntennaConnected()");
+    auto halTuner = getHalTuner(nativeContext);
+    if (halTuner == nullptr) return false;
+
+    bool isConnected = false;
+    Result halResult;
+    auto hidlResult = halTuner->getConfiguration([&](Result result, const BandConfig& config) {
+        halResult = result;
+        isConnected = config.antennaConnected;
+    });
+    convert::ThrowIfFailed(env, hidlResult, halResult);
+    return isConnected;
 }
 
 static const JNINativeMethod gTunerMethods[] = {
@@ -249,6 +348,12 @@
     { "nativeCancel", "(J)V", (void*)nativeCancel },
     { "nativeGetProgramInformation", "(J)Landroid/hardware/radio/RadioManager$ProgramInfo;",
             (void*)nativeGetProgramInformation },
+    { "nativeStartBackgroundScan", "(J)Z", (void*)nativeStartBackgroundScan },
+    { "nativeGetProgramList", "(JLjava/lang/String;)Ljava/util/List;",
+            (void*)nativeGetProgramList },
+    { "nativeIsAnalogForced", "(J)Z", (void*)nativeIsAnalogForced },
+    { "nativeSetAnalogForced", "(JZ)V", (void*)nativeSetAnalogForced },
+    { "nativeIsAntennaConnected", "(J)Z", (void*)nativeIsAntennaConnected },
 };
 
 } // namespace Tuner
@@ -266,6 +371,11 @@
     gjni.Tuner.tunerCallback = GetFieldIDOrDie(env, tunerClass, "mTunerCallback",
             "Lcom/android/server/radio/TunerCallback;");
 
+    auto arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
+    gjni.ArrayList.clazz = MakeGlobalRefOrDie(env, arrayListClass);
+    gjni.ArrayList.cstor = GetMethodIDOrDie(env, arrayListClass, "<init>", "()V");
+    gjni.ArrayList.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
+
     auto res = jniRegisterNativeMethods(env, "com/android/server/radio/Tuner",
             gTunerMethods, NELEM(gTunerMethods));
     LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
diff --git a/services/core/jni/com_android_server_radio_convert.cpp b/services/core/jni/com_android_server_radio_convert.cpp
index e1404fc..19abf8a 100644
--- a/services/core/jni/com_android_server_radio_convert.cpp
+++ b/services/core/jni/com_android_server_radio_convert.cpp
@@ -37,6 +37,7 @@
 using V1_0::MetadataType;
 using V1_0::Result;
 using V1_0::Rds;
+using V1_1::ProgramListResult;
 
 static struct {
     struct {
@@ -78,23 +79,31 @@
         jmethodID putBitmapFromNative;
         jmethodID putClockFromNative;
     } RadioMetadata;
+
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+    } RuntimeException;
+
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+    } ParcelableException;
 } gjni;
 
-template <typename T>
-static bool ThrowIfFailedHidl(JNIEnv *env, const Return<T> &hidlResult) {
+bool __ThrowIfFailedHidl(JNIEnv *env, const hardware::details::return_status &hidlResult) {
     if (hidlResult.isOk()) return false;
 
-    jniThrowExceptionFmt(env, "java/lang/RuntimeException",
-            "HIDL call failed: %s", hidlResult.description().c_str());
+    ThrowParcelableRuntimeException(env, "HIDL call failed: " + hidlResult.description());
     return true;
 }
 
-static bool ThrowIfFailed(JNIEnv *env, const Result halResult) {
+bool __ThrowIfFailed(JNIEnv *env, const Result halResult) {
     switch (halResult) {
         case Result::OK:
             return false;
         case Result::NOT_INITIALIZED:
-            jniThrowRuntimeException(env, "Result::NOT_INITIALIZED");
+            ThrowParcelableRuntimeException(env, "Result::NOT_INITIALIZED");
             return true;
         case Result::INVALID_ARGUMENTS:
             jniThrowException(env, "java/lang/IllegalArgumentException",
@@ -104,22 +113,43 @@
             jniThrowException(env, "java/lang/IllegalStateException", "Result::INVALID_STATE");
             return true;
         case Result::TIMEOUT:
-            jniThrowRuntimeException(env, "Result::TIMEOUT (unexpected here)");
+            ThrowParcelableRuntimeException(env, "Result::TIMEOUT (unexpected here)");
             return true;
         default:
-            jniThrowExceptionFmt(env, "java/lang/RuntimeException",
-                    "Unknown failure, result: %d", halResult);
+            ThrowParcelableRuntimeException(env, "Unknown failure, result: "
+                    + std::to_string(static_cast<int32_t>(halResult)));
             return true;
     }
 }
 
-bool ThrowIfFailed(JNIEnv *env, const Return<void> &hidlResult, Result halResult) {
-    return ThrowIfFailedHidl(env, hidlResult) || ThrowIfFailed(env, halResult);
+bool __ThrowIfFailed(JNIEnv *env, const ProgramListResult halResult) {
+    switch (halResult) {
+        case ProgramListResult::NOT_READY:
+            jniThrowException(env, "java/lang/IllegalStateException", "Scan is in progress");
+            return true;
+        case ProgramListResult::NOT_STARTED:
+            jniThrowException(env, "java/lang/IllegalStateException", "Scan has not been started");
+            return true;
+        case ProgramListResult::UNAVAILABLE:
+            ThrowParcelableRuntimeException(env,
+                    "ProgramListResult::UNAVAILABLE (unexpected here)");
+            return true;
+        default:
+            return __ThrowIfFailed(env, static_cast<Result>(halResult));
+    }
 }
 
-bool ThrowIfFailed(JNIEnv *env, const Return<Result> &hidlResult) {
-    return ThrowIfFailedHidl(env, hidlResult)
-            || ThrowIfFailed(env, static_cast<Result>(hidlResult));
+void ThrowParcelableRuntimeException(JNIEnv *env, const std::string& msg) {
+    EnvWrapper wrap(env);
+
+    auto jMsg = wrap(env->NewStringUTF(msg.c_str()));
+    auto runtimeExc = wrap(env->NewObject(gjni.RuntimeException.clazz,
+            gjni.RuntimeException.cstor, jMsg.get()));
+    auto parcelableExc = wrap(env->NewObject(gjni.ParcelableException.clazz,
+            gjni.ParcelableException.cstor, runtimeExc.get()));
+
+    auto res = env->Throw(static_cast<jthrowable>(parcelableExc.get()));
+    ALOGE_IF(res != JNI_OK, "Couldn't throw parcelable runtime exception");
 }
 
 static Rds RdsForRegion(bool rds, Region region) {
@@ -278,19 +308,27 @@
     return jMetadata;
 }
 
-JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_1::ProgramInfo &info11) {
+static JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info10,
+        const V1_1::ProgramInfo *info11) {
     ALOGV("ProgramInfoFromHal()");
     EnvWrapper wrap(env);
 
-    auto& info10 = info11.base;
     auto jMetadata = MetadataFromHal(env, info10.metadata);
-    auto jVendorExtension = wrap(env->NewStringUTF(info11.vendorExension.c_str()));
+    auto jVendorExtension = info11 ?
+            wrap(env->NewStringUTF(info11->vendorExension.c_str())) : nullptr;
 
     return wrap(env->NewObject(gjni.ProgramInfo.clazz, gjni.ProgramInfo.cstor, info10.channel,
             info10.subChannel, info10.tuned, info10.stereo, info10.digital, info10.signalStrength,
-            jMetadata.get(), info11.flags, jVendorExtension.get()));
+            jMetadata.get(), info11 ? info11->flags : 0, jVendorExtension.get()));
 }
 
+JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info) {
+    return ProgramInfoFromHal(env, info, nullptr);
+}
+
+JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_1::ProgramInfo &info) {
+    return ProgramInfoFromHal(env, info.base, &info);
+}
 
 } // namespace convert
 } // namespace radio
@@ -344,6 +382,16 @@
             "putBitmapFromNative", "(I[B)I");
     gjni.RadioMetadata.putClockFromNative = GetMethodIDOrDie(env, radioMetadataClass,
             "putClockFromNative", "(IJI)I");
+
+    auto runtimeExcClass = FindClassOrDie(env, "java/lang/RuntimeException");
+    gjni.RuntimeException.clazz = MakeGlobalRefOrDie(env, runtimeExcClass);
+    gjni.RuntimeException.cstor = GetMethodIDOrDie(env, runtimeExcClass, "<init>",
+            "(Ljava/lang/String;)V");
+
+    auto parcelableExcClass = FindClassOrDie(env, "android/os/ParcelableException");
+    gjni.ParcelableException.clazz = MakeGlobalRefOrDie(env, parcelableExcClass);
+    gjni.ParcelableException.cstor = GetMethodIDOrDie(env, parcelableExcClass, "<init>",
+            "(Ljava/lang/Throwable;)V");
 }
 
 } // namespace android
diff --git a/services/core/jni/com_android_server_radio_convert.h b/services/core/jni/com_android_server_radio_convert.h
index 811f653..6f6774b 100644
--- a/services/core/jni/com_android_server_radio_convert.h
+++ b/services/core/jni/com_android_server_radio_convert.h
@@ -34,16 +34,33 @@
 namespace V1_0 = hardware::broadcastradio::V1_0;
 namespace V1_1 = hardware::broadcastradio::V1_1;
 
-bool ThrowIfFailed(JNIEnv *env, const hardware::Return<V1_0::Result> &hidlResult);
-bool ThrowIfFailed(JNIEnv *env, const hardware::Return<void> &hidlResult, V1_0::Result halResult);
-
 JavaRef<jobject> BandConfigFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region);
 V1_0::BandConfig BandConfigToHal(JNIEnv *env, jobject jConfig, Region &region);
 
 V1_0::Direction DirectionToHal(bool directionDown);
 
+JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info);
 JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_1::ProgramInfo &info);
 
+
+void ThrowParcelableRuntimeException(JNIEnv *env, const std::string& msg);
+
+// These three are only for internal use by template functions below.
+bool __ThrowIfFailedHidl(JNIEnv *env,
+        const hardware::details::return_status &hidlResult);
+bool __ThrowIfFailed(JNIEnv *env, const V1_0::Result halResult);
+bool __ThrowIfFailed(JNIEnv *env, const V1_1::ProgramListResult halResult);
+
+template <typename T>
+bool ThrowIfFailed(JNIEnv *env, const hardware::Return<void> &hidlResult, const T halResult) {
+    return __ThrowIfFailedHidl(env, hidlResult) || __ThrowIfFailed(env, halResult);
+}
+
+template <typename T>
+bool ThrowIfFailed(JNIEnv *env, const hardware::Return<T> &hidlResult) {
+    return __ThrowIfFailedHidl(env, hidlResult) || __ThrowIfFailed(env, static_cast<T>(hidlResult));
+}
+
 } // namespace convert
 } // namespace radio
 } // namespace server
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 79c9b417..c3617e0 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -42,6 +42,7 @@
 int register_android_server_location_ContextHubService(JNIEnv* env);
 int register_android_server_location_GnssLocationProvider(JNIEnv* env);
 int register_android_server_connectivity_Vpn(JNIEnv* env);
+int register_android_server_connectivity_tethering_OffloadHardwareInterface(JNIEnv*);
 int register_android_server_hdmi_HdmiCecController(JNIEnv* env);
 int register_android_server_tv_TvUinputBridge(JNIEnv* env);
 int register_android_server_tv_TvInputHal(JNIEnv* env);
@@ -84,6 +85,7 @@
     register_android_server_location_ContextHubService(env);
     register_android_server_location_GnssLocationProvider(env);
     register_android_server_connectivity_Vpn(env);
+    register_android_server_connectivity_tethering_OffloadHardwareInterface(env);
     register_android_server_ConsumerIrService(env);
     register_android_server_BatteryStatsService(env);
     register_android_server_hdmi_HdmiCecController(env);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 3113cb3..836f0b8 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1670,6 +1670,7 @@
         final MediaRouterService mediaRouterF = mediaRouter;
         final MmsServiceBroker mmsServiceF = mmsService;
         final IpSecService ipSecServiceF = ipSecService;
+        final WindowManagerService windowManagerF = wm;
 
         // We now tell the activity manager it is okay to run third party
         // code.  It will call back into us once it has gotten to the state
@@ -1709,7 +1710,7 @@
 
             traceBeginAndSlog("StartSystemUI");
             try {
-                startSystemUi(context);
+                startSystemUi(context, windowManagerF);
             } catch (Throwable e) {
                 reportWtf("starting System UI", e);
             }
@@ -1863,13 +1864,14 @@
         }, BOOT_TIMINGS_TRACE_LOG);
     }
 
-    static final void startSystemUi(Context context) {
+    static final void startSystemUi(Context context, WindowManagerService windowManager) {
         Intent intent = new Intent();
         intent.setComponent(new ComponentName("com.android.systemui",
                     "com.android.systemui.SystemUIService"));
         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
         //Slog.d(TAG, "Starting service: " + intent);
         context.startServiceAsUser(intent, UserHandle.SYSTEM);
+        windowManager.onSystemUiStarted();
     }
 
     private static void traceBeginAndSlog(String name) {
diff --git a/services/net/java/android/net/util/SharedLog.java b/services/net/java/android/net/util/SharedLog.java
new file mode 100644
index 0000000..343d237
--- /dev/null
+++ b/services/net/java/android/net/util/SharedLog.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package android.net.util;
+
+import android.text.TextUtils;
+import android.util.LocalLog;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.StringJoiner;
+
+
+/**
+ * Class to centralize logging functionality for tethering.
+ *
+ * All access to class methods other than dump() must be on the same thread.
+ *
+ * @hide
+ */
+public class SharedLog {
+    private final static int DEFAULT_MAX_RECORDS = 500;
+    private final static String COMPONENT_DELIMITER = ".";
+
+    private enum Category {
+        NONE,
+        ERROR,
+        MARK,
+        WARN,
+    };
+
+    private final LocalLog mLocalLog;
+    // The tag to use for output to the system log. This is not output to the
+    // LocalLog because that would be redundant.
+    private final String mTag;
+    // The component (or subcomponent) of a system that is sharing this log.
+    // This can grow in depth if components call forSubComponent() to obtain
+    // their SharedLog instance. The tag is not included in the component for
+    // brevity.
+    private final String mComponent;
+
+    public SharedLog(String tag) {
+        this(DEFAULT_MAX_RECORDS, tag);
+    }
+
+    public SharedLog(int maxRecords, String tag) {
+        this(new LocalLog(maxRecords), tag, tag);
+    }
+
+    private SharedLog(LocalLog localLog, String tag, String component) {
+        mLocalLog = localLog;
+        mTag = tag;
+        mComponent = component;
+    }
+
+    public SharedLog forSubComponent(String component) {
+        if (!isRootLogInstance()) {
+            component = mComponent + COMPONENT_DELIMITER + component;
+        }
+        return new SharedLog(mLocalLog, mTag, component);
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+        mLocalLog.readOnlyLocalLog().dump(fd, writer, args);
+    }
+
+    //////
+    // Methods that both log an entry and emit it to the system log.
+    //////
+
+    public void e(Exception e) {
+        Log.e(mTag, record(Category.ERROR, e.toString()));
+    }
+
+    public void e(String msg) {
+        Log.e(mTag, record(Category.ERROR, msg));
+    }
+
+    public void i(String msg) {
+        Log.i(mTag, record(Category.NONE, msg));
+    }
+
+    public void w(String msg) {
+        Log.w(mTag, record(Category.WARN, msg));
+    }
+
+    //////
+    // Methods that only log an entry (and do NOT emit to the system log).
+    //////
+
+    public void log(String msg) {
+        record(Category.NONE, msg);
+    }
+
+    public void mark(String msg) {
+        record(Category.MARK, msg);
+    }
+
+    private String record(Category category, String msg) {
+        final String entry = logLine(category, msg);
+        mLocalLog.log(entry);
+        return entry;
+    }
+
+    private String logLine(Category category, String msg) {
+        final StringJoiner sj = new StringJoiner(" ");
+        if (!isRootLogInstance()) sj.add("[" + mComponent + "]");
+        if (category != Category.NONE) sj.add(category.toString());
+        return sj.add(msg).toString();
+    }
+
+    // Check whether this SharedLog instance is nominally the top level in
+    // a potential hierarchy of shared logs (the root of a tree),
+    // or is a subcomponent within the hierarchy.
+    private boolean isRootLogInstance() {
+        return TextUtils.isEmpty(mComponent) || mComponent.equals(mTag);
+    }
+}
diff --git a/services/tests/notification/AndroidTest.xml b/services/tests/notification/AndroidTest.xml
index 0e72c5e..fa77407 100644
--- a/services/tests/notification/AndroidTest.xml
+++ b/services/tests/notification/AndroidTest.xml
@@ -19,6 +19,7 @@
     </target_preparer>
 
     <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="framework-base-presubmit" />
     <option name="test-tag" value="FrameworksNotificationTests" />
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.tests.notification" />
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
index 267d2a6..0812783 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
@@ -99,7 +99,7 @@
         when(mMockContext.getPackageManager()).thenReturn(mPm);
 
         legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
-        upgrade.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
+        upgrade.targetSdkVersion = Build.VERSION_CODES.O;
         try {
             when(mPm.getApplicationInfoAsUser(eq(pkg), anyInt(), anyInt())).thenReturn(legacy);
             when(mPm.getApplicationInfoAsUser(eq(pkg2), anyInt(), anyInt())).thenReturn(upgrade);
diff --git a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
index 0f8c815..2c9c114 100644
--- a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
@@ -119,7 +119,7 @@
         final ApplicationInfo legacy = new ApplicationInfo();
         legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
         final ApplicationInfo upgrade = new ApplicationInfo();
-        upgrade.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
+        upgrade.targetSdkVersion = Build.VERSION_CODES.O;
         when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(legacy);
         when(mPm.getApplicationInfoAsUser(eq(UPDATED_PKG), anyInt(), anyInt())).thenReturn(upgrade);
         when(mPm.getPackageUidAsUser(eq(PKG), anyInt())).thenReturn(UID);
@@ -1232,6 +1232,15 @@
     }
 
     @Test
+    public void testBadgingForUserAll() throws Exception {
+        try {
+            mHelper.badgingEnabled(UserHandle.ALL);
+        } catch (Exception e) {
+            fail("just don't throw");
+        }
+    }
+
+    @Test
     public void testBadgingOverrideUserIsolation() throws Exception {
         Secure.putIntForUser(getContext().getContentResolver(),
                 Secure.NOTIFICATION_BADGING, 0,
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/ActionReplacingCallbackTest.java b/services/tests/servicestests/src/com/android/server/accessibility/ActionReplacingCallbackTest.java
index 8afe853..72820f1 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/ActionReplacingCallbackTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/ActionReplacingCallbackTest.java
@@ -25,6 +25,9 @@
 import android.view.accessibility.IAccessibilityInteractionConnection;
 import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
 
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
@@ -45,12 +48,13 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyObject;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
 import static org.mockito.MockitoAnnotations.initMocks;
 
 /**
@@ -63,15 +67,50 @@
     private static final int NON_ROOT_NODE_ID = 0xAAAA5555;
     private static final long INTERROGATING_TID = 0x1234FACE;
 
-    private static final AccessibilityAction[] ACTIONS_FROM_REPLACER =
-            {ACTION_CLICK, ACTION_EXPAND};
-    private static final AccessibilityAction[] A11Y_FOCUS_ACTIONS =
-            {ACTION_ACCESSIBILITY_FOCUS, ACTION_CLEAR_ACCESSIBILITY_FOCUS};
     // We expect both the replacer actions and a11y focus actions to appear
     private static final AccessibilityAction[] REQUIRED_ACTIONS_ON_ROOT_TO_SERVICE =
             {ACTION_CLICK, ACTION_EXPAND, ACTION_ACCESSIBILITY_FOCUS,
                     ACTION_CLEAR_ACCESSIBILITY_FOCUS};
 
+    private static final Matcher<AccessibilityNodeInfo> HAS_NO_ACTIONS =
+            new BaseMatcher<AccessibilityNodeInfo>() {
+        @Override
+        public boolean matches(Object o) {
+            AccessibilityNodeInfo node = (AccessibilityNodeInfo) o;
+            if (!node.getActionList().isEmpty()) return false;
+            return (!node.isScrollable() && !node.isLongClickable() && !node.isClickable()
+                    && !node.isContextClickable() && !node.isDismissable() && !node.isFocusable());
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText("Has no actions");
+        }
+    };
+
+    private static final Matcher<AccessibilityNodeInfo> HAS_EXPECTED_ACTIONS_ON_ROOT =
+            new BaseMatcher<AccessibilityNodeInfo>() {
+                @Override
+                public boolean matches(Object o) {
+                    AccessibilityNodeInfo node = (AccessibilityNodeInfo) o;
+                    List<AccessibilityAction> actions = node.getActionList();
+                    if ((actions.size() != 4) || !actions.contains(ACTION_CLICK)
+                            || !actions.contains(ACTION_EXPAND)
+                            || !actions.contains(ACTION_ACCESSIBILITY_FOCUS)) {
+                        return false;
+                    }
+                    return (!node.isScrollable() && !node.isLongClickable()
+                            && !node.isLongClickable() && node.isClickable()
+                            && !node.isContextClickable() && !node.isDismissable()
+                            && !node.isFocusable());
+                }
+
+                @Override
+                public void describeTo(Description description) {
+                    description.appendText("Has only 4 actions expected on root");
+                }
+            };
+
     @Mock IAccessibilityInteractionConnectionCallback mMockServiceCallback;
     @Mock IAccessibilityInteractionConnection mMockReplacerConnection;
 
@@ -118,9 +157,10 @@
                 eq(INTERACTION_ID));
         AccessibilityNodeInfo infoSentToService = mInfoCaptor.getValue();
         assertEquals(AccessibilityNodeInfo.ROOT_NODE_ID, infoSentToService.getSourceNodeId());
-        assertInfoHasExactlyTheseActions(infoSentToService, REQUIRED_ACTIONS_ON_ROOT_TO_SERVICE);
+        assertThat(infoSentToService, HAS_EXPECTED_ACTIONS_ON_ROOT);
     }
 
+    @Test
     public void testCallbacks_singleNonrootNodeThenReplacer_returnsNodeWithNoActions()
             throws RemoteException {
         AccessibilityNodeInfo infoFromApp = AccessibilityNodeInfo.obtain();
@@ -136,9 +176,10 @@
                 eq(INTERACTION_ID));
         AccessibilityNodeInfo infoSentToService = mInfoCaptor.getValue();
         assertEquals(NON_ROOT_NODE_ID, infoSentToService.getSourceNodeId());
-        assertTrue(infoSentToService.getActionList().isEmpty());
+        assertThat(infoSentToService, HAS_NO_ACTIONS);
     }
 
+    @Test
     public void testCallbacks_replacerThenSingleRootNode_returnsNodeWithReplacedActions()
             throws RemoteException {
         mActionReplacingCallback.setFindAccessibilityNodeInfosResult(getReplacerNodes(),
@@ -154,9 +195,10 @@
                 eq(INTERACTION_ID));
         AccessibilityNodeInfo infoSentToService = mInfoCaptor.getValue();
         assertEquals(AccessibilityNodeInfo.ROOT_NODE_ID, infoSentToService.getSourceNodeId());
-        assertInfoHasExactlyTheseActions(infoSentToService, REQUIRED_ACTIONS_ON_ROOT_TO_SERVICE);
+        assertThat(infoSentToService, HAS_EXPECTED_ACTIONS_ON_ROOT);
     }
 
+    @Test
     public void testCallbacks_multipleNodesThenReplacer_clearsActionsAndAddsSomeToRoot()
             throws RemoteException {
         mActionReplacingCallback
@@ -173,11 +215,11 @@
                 mInfoListCaptor.getValue(), AccessibilityNodeInfo.ROOT_NODE_ID);
         AccessibilityNodeInfo otherInfoSentToService = getNodeWithIdFromList(
                 mInfoListCaptor.getValue(), NON_ROOT_NODE_ID);
-        assertInfoHasExactlyTheseActions(
-                rootInfoSentToService, REQUIRED_ACTIONS_ON_ROOT_TO_SERVICE);
-        assertTrue(otherInfoSentToService.getActionList().isEmpty());
+        assertThat(rootInfoSentToService, HAS_EXPECTED_ACTIONS_ON_ROOT);
+        assertThat(otherInfoSentToService, HAS_NO_ACTIONS);
     }
 
+    @Test
     public void testCallbacks_replacerThenMultipleNodes_clearsActionsAndAddsSomeToRoot()
             throws RemoteException {
         mActionReplacingCallback.setFindAccessibilityNodeInfosResult(getReplacerNodes(),
@@ -194,18 +236,18 @@
                 mInfoListCaptor.getValue(), AccessibilityNodeInfo.ROOT_NODE_ID);
         AccessibilityNodeInfo otherInfoSentToService = getNodeWithIdFromList(
                 mInfoListCaptor.getValue(), NON_ROOT_NODE_ID);
-        assertInfoHasExactlyTheseActions(
-                rootInfoSentToService, REQUIRED_ACTIONS_ON_ROOT_TO_SERVICE);
-        assertTrue(otherInfoSentToService.getActionList().isEmpty());
+        assertThat(rootInfoSentToService, HAS_EXPECTED_ACTIONS_ON_ROOT);
+        assertThat(otherInfoSentToService, HAS_NO_ACTIONS);
     }
 
+    @Test
     public void testConstructor_actionReplacerThrowsException_passesDataToService()
             throws RemoteException {
         doThrow(RemoteException.class).when(mMockReplacerConnection)
                 .findAccessibilityNodeInfoByAccessibilityId(eq(AccessibilityNodeInfo.ROOT_NODE_ID),
-                        (Region) anyObject(), mInteractionIdCaptor.capture(),
-                        eq(mActionReplacingCallback), eq(0), eq(INTERROGATING_PID),
-                        eq(INTERROGATING_TID), (MagnificationSpec) anyObject(), eq(null));
+                        (Region) anyObject(), anyInt(), (ActionReplacingCallback) anyObject(),
+                        eq(0),  eq(INTERROGATING_PID), eq(INTERROGATING_TID),
+                        (MagnificationSpec) anyObject(), eq(null));
         ActionReplacingCallback actionReplacingCallback = new ActionReplacingCallback(
                 mMockServiceCallback, mMockReplacerConnection, INTERACTION_ID, INTERROGATING_PID,
                 INTERROGATING_TID);
@@ -214,16 +256,17 @@
         AccessibilityNodeInfo infoFromApp = AccessibilityNodeInfo.obtain();
         infoFromApp.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID, APP_WINDOW_ID);
         infoFromApp.addAction(ACTION_CONTEXT_CLICK);
+        infoFromApp.setContextClickable(true);
         actionReplacingCallback.setFindAccessibilityNodeInfoResult(infoFromApp, INTERACTION_ID);
 
         verify(mMockServiceCallback).setFindAccessibilityNodeInfoResult(mInfoCaptor.capture(),
                 eq(INTERACTION_ID));
         AccessibilityNodeInfo infoSentToService = mInfoCaptor.getValue();
         assertEquals(AccessibilityNodeInfo.ROOT_NODE_ID, infoSentToService.getSourceNodeId());
-        assertEquals(1, infoSentToService.getActionList().size());
-        assertEquals(ACTION_CONTEXT_CLICK, infoSentToService.getActionList().get(0));
+        assertThat(infoSentToService, HAS_NO_ACTIONS);
     }
 
+    @Test
     public void testSetPerformAccessibilityActionResult_actsAsPassThrough() throws RemoteException {
         mActionReplacingCallback.setPerformAccessibilityActionResult(true, INTERACTION_ID);
         verify(mMockServiceCallback).setPerformAccessibilityActionResult(true, INTERACTION_ID);
@@ -236,9 +279,9 @@
         AccessibilityNodeInfo root = AccessibilityNodeInfo.obtain();
         root.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID,
                 AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID);
-        for (AccessibilityAction action : ACTIONS_FROM_REPLACER) {
-            root.addAction(action);
-        }
+        root.addAction(ACTION_CLICK);
+        root.addAction(ACTION_EXPAND);
+        root.setClickable(true);
 
         // Second node should have no effect
         AccessibilityNodeInfo other = AccessibilityNodeInfo.obtain();
@@ -249,13 +292,6 @@
         return Arrays.asList(root, other);
     }
 
-    private void assertInfoHasExactlyTheseActions(
-            AccessibilityNodeInfo info, AccessibilityAction[] actions) {
-        List<AccessibilityAction> nodeActions = info.getActionList();
-        assertEquals(new HashSet<AccessibilityAction>(nodeActions),
-                new HashSet<AccessibilityAction>(Arrays.asList(actions)));
-    }
-
     private AccessibilityNodeInfo getNodeWithIdFromList(
             List<AccessibilityNodeInfo> infos, long id) {
         for (AccessibilityNodeInfo info : infos) {
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/FullBackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/FullBackupUtilsTest.java
new file mode 100644
index 0000000..4e3de64
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/FullBackupUtilsTest.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 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
+ */
+
+package com.android.server.backup.utils;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.os.ParcelFileDescriptor;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Random;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class FullBackupUtilsTest {
+    @Mock private ParcelFileDescriptor mParcelFileDescriptorMock;
+    @Mock private OutputStream mOutputStreamMock;
+    private File mTemporaryFile;
+    private ByteArrayOutputStream mByteArrayOutputStream;
+    private ParcelFileDescriptor mTemporaryFileDescriptor;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mTemporaryFile = File.createTempFile("backup-data", ".txt");
+        mByteArrayOutputStream = new ByteArrayOutputStream();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mTemporaryFileDescriptor != null) {
+            mTemporaryFileDescriptor.close();
+        }
+        if (mTemporaryFile != null) {
+            mTemporaryFile.delete();
+        }
+    }
+
+    @Test
+    public void routeSocketDataToOutput_inPipeIsNull_throwsNPE() throws Exception {
+        try {
+            FullBackupUtils.routeSocketDataToOutput(null, mOutputStreamMock);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    @Test
+    public void routeSocketDataToOutput_outNull_throwsNPE() throws Exception {
+        try {
+            FullBackupUtils.routeSocketDataToOutput(mParcelFileDescriptorMock, null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    @Test
+    public void routeSocketDataToOutput_emptyInput_throwsEOFException() throws Exception {
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        try {
+            FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                    mOutputStreamMock);
+            fail();
+        } catch (EOFException expected) {
+        }
+
+        verifyZeroInteractions(mOutputStreamMock);
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_incompleteChunkSizeInput_throwsEOFException()
+            throws Exception {
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeByte(100);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        try {
+            FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                    mOutputStreamMock);
+            fail();
+        } catch (EOFException expected) {
+        }
+
+        verifyZeroInteractions(mOutputStreamMock);
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_validEmptyInput_doesNotWriteAnything() throws Exception {
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(0);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor, mOutputStreamMock);
+
+        verifyZeroInteractions(mOutputStreamMock);
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_notEnoughData_throwsEOFException() throws Exception {
+        byte[] data = createFakeDataArray(100);
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(data.length + 1);
+        outputStream.write(data);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        try {
+            FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                    mByteArrayOutputStream);
+            fail();
+        } catch (EOFException expected) {
+        }
+
+        verify(mOutputStreamMock, never()).close();
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_oneSmallChunk_writesOutputCorrectly() throws Exception {
+        byte[] data = createFakeDataArray(100);
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(data.length);
+        outputStream.write(data);
+        outputStream.writeInt(0);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                mByteArrayOutputStream);
+
+        assertThat(mByteArrayOutputStream.toByteArray()).isEqualTo(data);
+        verify(mOutputStreamMock, never()).close();
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_oneLargeChunk_writesOutputCorrectly() throws Exception {
+        byte[] data = createFakeDataArray(128000);
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(data.length);
+        outputStream.write(data);
+        outputStream.writeInt(0);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                mByteArrayOutputStream);
+
+        assertThat(mByteArrayOutputStream.toByteArray()).isEqualTo(data);
+        verify(mOutputStreamMock, never()).close();
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_twoSmallChunks_writesOutputCorrectly() throws Exception {
+        byte[] data = createFakeDataArray(200);
+        int chunk1Length = 97;
+        int chunk2Length = data.length - chunk1Length;
+
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(chunk1Length);
+        outputStream.write(data, 0, chunk1Length);
+        outputStream.writeInt(chunk2Length);
+        outputStream.write(data, chunk1Length, chunk2Length);
+        outputStream.writeInt(0);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                mByteArrayOutputStream);
+
+        assertThat(mByteArrayOutputStream.toByteArray()).isEqualTo(data);
+        verify(mOutputStreamMock, never()).close();
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    @Test
+    public void routeSocketDataToOutput_twoLargeChunks_writesOutputCorrectly() throws Exception {
+        byte[] data = createFakeDataArray(256000);
+        int chunk1Length = 127313;
+        int chunk2Length = data.length - chunk1Length;
+
+        DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(mTemporaryFile));
+        outputStream.writeInt(chunk1Length);
+        outputStream.write(data, 0, chunk1Length);
+        outputStream.writeInt(chunk2Length);
+        outputStream.write(data, chunk1Length, chunk2Length);
+        outputStream.writeInt(0);
+        outputStream.close();
+
+        mTemporaryFileDescriptor = ParcelFileDescriptor.open(mTemporaryFile,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+
+        FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor,
+                mByteArrayOutputStream);
+
+        assertThat(mByteArrayOutputStream.toByteArray()).isEqualTo(data);
+        verify(mOutputStreamMock, never()).close();
+        assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
+    }
+
+    private static byte[] createFakeDataArray(int length) {
+        byte[] data = new byte[length];
+        new Random(3742).nextBytes(data);
+        return data;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
index a2b4568..7de46d9 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
@@ -31,6 +31,7 @@
 import android.os.FileUtils;
 import android.os.IProgressListener;
 import android.os.UserManager;
+import android.os.storage.StorageManager;
 import android.security.KeyStore;
 import android.test.AndroidTestCase;
 
@@ -85,7 +86,7 @@
         mDevicePolicyManager = mock(DevicePolicyManager.class);
 
         mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager,
-                mDevicePolicyManager);
+                mDevicePolicyManager, mock(StorageManager.class));
         mStorage = new LockSettingsStorageTestable(mContext,
                 new File(getContext().getFilesDir(), "locksettings"));
         File storageDir = mStorage.mStorageDir;
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
index 4665441..449a54c 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
@@ -28,6 +28,7 @@
 import android.database.sqlite.SQLiteDatabase;
 import android.os.FileUtils;
 import android.os.UserManager;
+import android.os.storage.StorageManager;
 import android.test.AndroidTestCase;
 
 import com.android.internal.widget.LockPatternUtils;
@@ -69,7 +70,8 @@
         when(mockUserManager.getProfileParent(eq(3))).thenReturn(new UserInfo(0, "name", 0));
 
         MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager,
-                mock(NotificationManager.class), mock(DevicePolicyManager.class));
+                mock(NotificationManager.class), mock(DevicePolicyManager.class),
+                mock(StorageManager.class));
         mStorage = new LockSettingsStorageTestable(context,
                 new File(getContext().getFilesDir(), "locksettings"));
         mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
@@ -336,7 +338,7 @@
         assertArrayEquals(data, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
         assertEquals(null, mStorage.readSyntheticPasswordState(0, 1234L, "state"));
 
-        mStorage.deleteSyntheticPasswordState(10, 1234L, "state", true);
+        mStorage.deleteSyntheticPasswordState(10, 1234L, "state");
         assertEquals(null, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
index c76a83e..8da33a8 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
@@ -21,19 +21,23 @@
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.os.UserManager;
+import android.os.storage.StorageManager;
 
 public class MockLockSettingsContext extends ContextWrapper {
 
     private UserManager mUserManager;
     private NotificationManager mNotificationManager;
     private DevicePolicyManager mDevicePolicyManager;
+    private StorageManager mStorageManager;
 
     public MockLockSettingsContext(Context base, UserManager userManager,
-            NotificationManager notificationManager, DevicePolicyManager devicePolicyManager) {
+            NotificationManager notificationManager, DevicePolicyManager devicePolicyManager,
+            StorageManager storageManager) {
         super(base);
         mUserManager = userManager;
         mNotificationManager = notificationManager;
         mDevicePolicyManager = devicePolicyManager;
+        mStorageManager = storageManager;
     }
 
     @Override
@@ -44,6 +48,8 @@
             return mNotificationManager;
         } else if (DEVICE_POLICY_SERVICE.equals(name)) {
             return mDevicePolicyManager;
+        } else if (STORAGE_SERVICE.equals(name)) {
+            return mStorageManager;
         } else {
             throw new RuntimeException("System service not mocked: " + name);
         }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockStorageManager.java b/services/tests/servicestests/src/com/android/server/locksettings/MockStorageManager.java
index ac46bae..89e18b4 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/MockStorageManager.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockStorageManager.java
@@ -500,4 +500,9 @@
         throw new UnsupportedOperationException();
     }
 
+    @Override
+    public void secdiscard(String path) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index 5e4ba7be..25ba66e 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -25,9 +25,12 @@
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.CoreMatchers.notNullValue;
 import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import android.annotation.NonNull;
@@ -37,6 +40,7 @@
 import android.content.pm.UserInfo;
 import android.os.UserHandle;
 import android.os.UserManagerInternal;
+import android.security.keystore.ArrayUtils;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -57,6 +61,7 @@
 import java.io.IOException;
 import java.security.PublicKey;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 @RunWith(AndroidJUnit4.class)
@@ -527,6 +532,41 @@
                 false /*notLaunched*/, false /*stopped*/, true /*installed*/);
     }
 
+    @Test
+    public void testInsertPackageSetting() {
+        final PackageSetting ps = createPackageSetting(0 /*sharedUserId*/, 0 /*pkgFlags*/);
+        final PackageParser.Package pkg = new PackageParser.Package(PACKAGE_NAME);
+        pkg.applicationInfo.setCodePath(ps.codePathString);
+        pkg.applicationInfo.setResourcePath(ps.resourcePathString);
+        final Settings settings =
+                new Settings(InstrumentationRegistry.getContext().getFilesDir(), new Object());
+        pkg.usesStaticLibraries = new ArrayList<>(
+                Arrays.asList("foo.bar1", "foo.bar2", "foo.bar3"));
+        pkg.usesStaticLibrariesVersions = new int[] {2, 4, 6};
+        settings.insertPackageSettingLPw(ps, pkg);
+        assertEquals(pkg, ps.pkg);
+        assertArrayEquals(pkg.usesStaticLibraries.toArray(new String[0]), ps.usesStaticLibraries);
+        assertArrayEquals(pkg.usesStaticLibrariesVersions, ps.usesStaticLibrariesVersions);
+
+        pkg.usesStaticLibraries = null;
+        pkg.usesStaticLibrariesVersions = null;
+        settings.insertPackageSettingLPw(ps, pkg);
+        assertEquals(pkg, ps.pkg);
+        assertNull("Actual: " + Arrays.toString(ps.usesStaticLibraries), ps.usesStaticLibraries);
+        assertNull("Actual: " + Arrays.toString(ps.usesStaticLibrariesVersions),
+                ps.usesStaticLibrariesVersions);
+    }
+
+    private <T> void assertArrayEquals(T[] a, T[] b) {
+        assertTrue("Expected: " + Arrays.toString(a) + ", actual: " + Arrays.toString(b),
+                Arrays.equals(a, b));
+    }
+
+    private void assertArrayEquals(int[] a, int[] b) {
+        assertTrue("Expected: " + Arrays.toString(a) + ", actual: " + Arrays.toString(b),
+                Arrays.equals(a, b));
+    }
+
     private void verifyUserState(PackageUserState userState, PackageUserState oldUserState,
             boolean userStateChanged) {
         verifyUserState(userState, oldUserState, userStateChanged, false /*notLaunched*/,
diff --git a/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java b/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java
index a8c39c4..6706969 100644
--- a/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java
+++ b/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java
@@ -24,6 +24,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.content.ContextWrapper;
 import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
@@ -32,6 +33,7 @@
 import android.provider.Settings;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.test.mock.MockContentResolver;
 
 import com.android.internal.util.test.FakeSettingsProvider;
@@ -40,20 +42,20 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 import java.io.File;
 import java.util.ArrayList;
 
-@RunWith(JUnit4.class)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class PreloadAppsInstallerTest {
     private static final int TEST_DEMO_USER = 111;
 
-    private @Mock Context mContext;
+    private Context mContext;
     private @Mock IPackageManager mIpm;
     private MockContentResolver mContentResolver;
     private File mPreloadsAppsDirectory;
@@ -66,6 +68,7 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
         mContentResolver = new MockContentResolver(mContext);
         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
         when(mContext.getContentResolver()).thenReturn(mContentResolver);
@@ -89,7 +92,9 @@
 
     @After
     public void tearDown() {
-        FileUtils.deleteContentsAndDir(mPreloadsAppsDirectory);
+        if (mPreloadsAppsDirectory != null) {
+            FileUtils.deleteContentsAndDir(mPreloadsAppsDirectory);
+        }
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java b/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java
index ce5b8cb..2e13d29 100644
--- a/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java
@@ -38,6 +38,7 @@
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
@@ -59,6 +60,7 @@
 import android.provider.Settings;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.test.mock.MockContentProvider;
 import android.test.mock.MockContentResolver;
 import android.util.ArrayMap;
@@ -72,9 +74,9 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.mockito.compat.ArgumentMatcher;
 
@@ -82,7 +84,7 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-@RunWith(JUnit4.class)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class RetailDemoModeServiceTest {
     private static final int TEST_DEMO_USER = 111;
@@ -90,7 +92,7 @@
     private static final String TEST_CAMERA_PKG = "test.cameraapp";
     private static final String TEST_PRELOADS_DIR_NAME = "test_preloads";
 
-    private @Mock Context mContext;
+    private Context mContext;
     private @Mock UserManager mUm;
     private @Mock PackageManager mPm;
     private @Mock IPackageManager mIpm;
@@ -113,12 +115,11 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        Context originalContext = InstrumentationRegistry.getContext();
-        when(mContext.getApplicationInfo()).thenReturn(originalContext.getApplicationInfo());
-        when(mContext.getResources()).thenReturn(originalContext.getResources());
+        mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
         when(mContext.getSystemServiceName(eq(JobScheduler.class))).thenReturn(
                 Context.JOB_SCHEDULER_SERVICE);
         when(mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE)).thenReturn(mJobScheduler);
+        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUm);
         mContentResolver = new MockContentResolver(mContext);
         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
         mContactsProvider = new MockContactsProvider(mContext);
@@ -129,12 +130,10 @@
         mTestPreloadsDir = new File(InstrumentationRegistry.getContext().getFilesDir(),
                 TEST_PRELOADS_DIR_NAME);
 
-        Settings.Global.putString(mContentResolver,
-                Settings.Global.RETAIL_DEMO_MODE_CONSTANTS, "");
-        Settings.Global.putInt(mContentResolver,
-                Settings.Global.DEVICE_PROVISIONED, 1);
-        Settings.Global.putInt(mContentResolver,
-                Settings.Global.DEVICE_DEMO_MODE, 1);
+        Settings.Global.putString(mContentResolver, Settings.Global.RETAIL_DEMO_MODE_CONSTANTS, "");
+        Settings.Global.putInt(mContentResolver, Settings.Global.DEVICE_PROVISIONED, 1);
+        Settings.Global.putInt(mContentResolver, Settings.Global.DEVICE_DEMO_MODE, 1);
+
         // Initialize RetailDemoModeService
         mInjector = new TestInjector();
         mService = new RetailDemoModeService(mInjector);
@@ -143,7 +142,9 @@
 
     @After
     public void tearDown() {
-        FileUtils.deleteContentsAndDir(mTestPreloadsDir);
+        if (mTestPreloadsDir != null) {
+            FileUtils.deleteContentsAndDir(mTestPreloadsDir);
+        }
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
index dcbedb6..da3b9c9 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
@@ -97,7 +97,8 @@
         final WindowTestUtils.TestAppWindowContainerController controller =
                 createAppWindowController();
         controller.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
-                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true);
+                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
+                false);
         waitUntilHandlersIdle();
         final AppWindowToken atoken = controller.getAppWindowToken(mDisplayContent);
         assertHasStartingWindow(atoken);
@@ -113,11 +114,12 @@
         final WindowTestUtils.TestAppWindowContainerController controller2 =
                 createAppWindowController();
         controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
-                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true);
+                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
+                false);
         waitUntilHandlersIdle();
         controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(),
-                true, true, false, true);
+                true, true, false, true, false);
         waitUntilHandlersIdle();
         assertNoStartingWindow(controller1.getAppWindowToken(mDisplayContent));
         assertHasStartingWindow(controller2.getAppWindowToken(mDisplayContent));
@@ -134,10 +136,11 @@
             // Surprise, ...! Transfer window in the middle of the creation flow.
             controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
                     android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(),
-                    true, true, false, true);
+                    true, true, false, true, false);
         });
         controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
-                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true);
+                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
+                false);
         waitUntilHandlersIdle();
         assertNoStartingWindow(controller1.getAppWindowToken(mDisplayContent));
         assertHasStartingWindow(controller2.getAppWindowToken(mDisplayContent));
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index f9254ad..856e940 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -34,6 +34,7 @@
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.SparseIntArray;
 
 import java.util.Arrays;
 import java.util.LinkedList;
@@ -239,7 +240,7 @@
     @Test
     @Ignore
     public void testFocusedWindowMultipleDisplays() throws Exception {
-        // Create a focusable window and check that focus is calcualted correctly
+        // Create a focusable window and check that focus is calculated correctly
         final WindowState window1 =
                 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "window1");
         assertEquals(window1, sWm.mRoot.computeFocusedWindow());
@@ -310,6 +311,24 @@
         assertEquals(afterStackCount - 1, mDisplayContent.getStaskPosById(PINNED_STACK_ID));
     }
 
+    /**
+     * Test that WM does not report displays to AM that are pending to be removed.
+     */
+    @Test
+    public void testDontReportDeferredRemoval() {
+        // Create a display and add an animating window to it.
+        final DisplayContent dc = createNewDisplay();
+        final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
+        window.mAnimatingExit = true;
+        // Request display removal, it should be deferred.
+        dc.removeIfPossible();
+        // Request ordered display ids from WM.
+        final SparseIntArray orderedDisplayIds = new SparseIntArray();
+        sWm.getDisplaysInFocusOrder(orderedDisplayIds);
+        // Make sure that display that is marked for removal is not reported.
+        assertEquals(-1, orderedDisplayIds.indexOfValue(dc.getDisplayId()));
+    }
+
     private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth,
                              int expectedBaseHeight, int expectedBaseDensity) {
         assertEquals(displayContent.mBaseDisplayWidth, expectedBaseWidth);
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
index 8108909..39c0de8 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
@@ -90,14 +90,42 @@
         long ms = SystemClock.elapsedRealtime();
         mPersister.persistSnapshot(1, mTestUserId, createSnapshot());
         mPersister.persistSnapshot(2, mTestUserId, createSnapshot());
-        mPersister.persistSnapshot(3, mTestUserId, createSnapshot());
-        mPersister.persistSnapshot(4, mTestUserId, createSnapshot());
-        mPersister.persistSnapshot(5, mTestUserId, createSnapshot());
-        mPersister.persistSnapshot(6, mTestUserId, createSnapshot());
+        mPersister.removeObsoleteFiles(new ArraySet<>(), new int[] { mTestUserId });
+        mPersister.removeObsoleteFiles(new ArraySet<>(), new int[] { mTestUserId });
+        mPersister.removeObsoleteFiles(new ArraySet<>(), new int[] { mTestUserId });
+        mPersister.removeObsoleteFiles(new ArraySet<>(), new int[] { mTestUserId });
         mPersister.waitForQueueEmpty();
         assertTrue(SystemClock.elapsedRealtime() - ms > 500);
     }
 
+    /**
+     * Tests that too many store write queue items are being purged.
+     */
+    @Test
+    public void testPurging() {
+        mPersister.persistSnapshot(100, mTestUserId, createSnapshot());
+        mPersister.waitForQueueEmpty();
+        mPersister.setPaused(true);
+        mPersister.persistSnapshot(1, mTestUserId, createSnapshot());
+        mPersister.removeObsoleteFiles(new ArraySet<>(), new int[] { mTestUserId });
+        mPersister.persistSnapshot(2, mTestUserId, createSnapshot());
+        mPersister.persistSnapshot(3, mTestUserId, createSnapshot());
+        mPersister.persistSnapshot(4, mTestUserId, createSnapshot());
+        mPersister.setPaused(false);
+        mPersister.waitForQueueEmpty();
+
+        // Make sure 1,2 were purged but removeObsoleteFiles wasn't.
+        final File[] existsFiles = new File[] {
+                new File(sFilesDir.getPath() + "/snapshots/3.proto"),
+                new File(sFilesDir.getPath() + "/snapshots/4.proto")};
+        final File[] nonExistsFiles = new File[] {
+                new File(sFilesDir.getPath() + "/snapshots/100.proto"),
+                new File(sFilesDir.getPath() + "/snapshots/1.proto"),
+                new File(sFilesDir.getPath() + "/snapshots/1.proto")};
+        assertTrueForFiles(existsFiles, File::exists, " must exist");
+        assertTrueForFiles(nonExistsFiles, file -> !file.exists(), " must not exist");
+    }
+
     @Test
     public void testGetTaskId() {
         RemoveObsoleteFilesQueueItem removeObsoleteFilesQueueItem =
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index be53667..c457cb3 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -366,6 +366,11 @@
     }
 
     @Override
+    public void screenTurningOff(ScreenOffListener screenOffListener) {
+
+    }
+
+    @Override
     public void screenTurnedOff() {
 
     }
@@ -632,5 +637,14 @@
     @Override
     public void setRecentsVisibilityLw(boolean visible) {
 
-   }
+    }
+
+    @Override
+    public void onSystemUiStarted() {
+    }
+
+    @Override
+    public boolean canDismissBootAnimation() {
+        return true;
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
index d9349ed..b83532c 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
@@ -115,11 +115,11 @@
         }
 
         WindowState getFirstChild() {
-            return mChildren.getFirst();
+            return mChildren.peekFirst();
         }
 
         WindowState getLastChild() {
-            return mChildren.getLast();
+            return mChildren.peekLast();
         }
 
         int positionInParent() {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 4ba457d..912e7a8 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -39,6 +39,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.UserInfo;
@@ -80,6 +81,7 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.LocalServices;
 import com.android.server.SystemService;
 
 import java.io.File;
@@ -137,6 +139,7 @@
     AppOpsManager mAppOps;
     UserManager mUserManager;
     PackageManager mPackageManager;
+    PackageManagerInternal mPackageManagerInternal;
     AppWidgetManager mAppWidgetManager;
     IDeviceIdleController mDeviceIdleController;
     private DisplayManager mDisplayManager;
@@ -179,6 +182,7 @@
         mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
         mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
         mPackageManager = getContext().getPackageManager();
+        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
         mHandler = new H(BackgroundThread.get().getLooper());
 
         File systemDataDir = new File(Environment.getDataDirectory(), "system");
@@ -407,6 +411,10 @@
         }
     }
 
+    private boolean shouldObfuscateInstantAppsForCaller(int callingUid) {
+        return !mPackageManagerInternal.canAccessInstantApps(callingUid);
+    }
+
     void clearAppIdleForPackage(String packageName, int userId) {
         synchronized (mAppIdleLock) {
             mAppIdleHistory.clearUsage(packageName, userId);
@@ -704,6 +712,11 @@
             final long elapsedRealtime = SystemClock.elapsedRealtime();
             convertToSystemTimeLocked(event);
 
+            if (event.getPackageName() != null
+                    && mPackageManagerInternal.isPackageEphemeral(userId, event.getPackageName())) {
+                event.mFlags |= Event.FLAG_IS_PACKAGE_INSTANT_APP;
+            }
+
             final UserUsageStatsService service =
                     getUserDataAndInitializeIfNeededLocked(userId, timeNow);
             service.reportEvent(event);
@@ -807,7 +820,8 @@
     /**
      * Called by the Binder stub.
      */
-    List<UsageStats> queryUsageStats(int userId, int bucketType, long beginTime, long endTime) {
+    List<UsageStats> queryUsageStats(int userId, int bucketType, long beginTime, long endTime,
+            boolean obfuscateInstantApps) {
         synchronized (mLock) {
             final long timeNow = checkAndGetTimeLocked();
             if (!validRange(timeNow, beginTime, endTime)) {
@@ -816,7 +830,23 @@
 
             final UserUsageStatsService service =
                     getUserDataAndInitializeIfNeededLocked(userId, timeNow);
-            return service.queryUsageStats(bucketType, beginTime, endTime);
+            List<UsageStats> list = service.queryUsageStats(bucketType, beginTime, endTime);
+            if (list == null) {
+                return null;
+            }
+
+            // Mangle instant app names *using their current state (not whether they were ephemeral
+            // when the data was recorded)*.
+            if (obfuscateInstantApps) {
+                for (int i = list.size() - 1; i >= 0; i--) {
+                    final UsageStats stats = list.get(i);
+                    if (mPackageManagerInternal.isPackageEphemeral(userId, stats.mPackageName)) {
+                        list.set(i, stats.getObfuscatedForInstantApp());
+                    }
+                }
+            }
+
+            return list;
         }
     }
 
@@ -840,7 +870,8 @@
     /**
      * Called by the Binder stub.
      */
-    UsageEvents queryEvents(int userId, long beginTime, long endTime) {
+    UsageEvents queryEvents(int userId, long beginTime, long endTime,
+            boolean shouldObfuscateInstantApps) {
         synchronized (mLock) {
             final long timeNow = checkAndGetTimeLocked();
             if (!validRange(timeNow, beginTime, endTime)) {
@@ -849,7 +880,7 @@
 
             final UserUsageStatsService service =
                     getUserDataAndInitializeIfNeededLocked(userId, timeNow);
-            return service.queryEvents(beginTime, endTime);
+            return service.queryEvents(beginTime, endTime, shouldObfuscateInstantApps);
         }
     }
 
@@ -884,10 +915,15 @@
         }
     }
 
-    boolean isAppIdleFilteredOrParoled(String packageName, int userId, long elapsedRealtime) {
+    boolean isAppIdleFilteredOrParoled(String packageName, int userId, long elapsedRealtime,
+            boolean shouldObfuscateInstantApps) {
         if (isParoledOrCharging()) {
             return false;
         }
+        if (shouldObfuscateInstantApps &&
+                mPackageManagerInternal.isPackageEphemeral(userId, packageName)) {
+            return false;
+        }
         return isAppIdleFiltered(packageName, getAppId(packageName), userId, elapsedRealtime);
     }
 
@@ -1353,11 +1389,14 @@
                 return null;
             }
 
+            final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller(
+                    Binder.getCallingUid());
+
             final int userId = UserHandle.getCallingUserId();
             final long token = Binder.clearCallingIdentity();
             try {
                 final List<UsageStats> results = UsageStatsService.this.queryUsageStats(
-                        userId, bucketType, beginTime, endTime);
+                        userId, bucketType, beginTime, endTime, obfuscateInstantApps);
                 if (results != null) {
                     return new ParceledListSlice<>(results);
                 }
@@ -1395,10 +1434,14 @@
                 return null;
             }
 
+            final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller(
+                    Binder.getCallingUid());
+
             final int userId = UserHandle.getCallingUserId();
             final long token = Binder.clearCallingIdentity();
             try {
-                return UsageStatsService.this.queryEvents(userId, beginTime, endTime);
+                return UsageStatsService.this.queryEvents(userId, beginTime, endTime,
+                        obfuscateInstantApps);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -1412,10 +1455,12 @@
             } catch (RemoteException re) {
                 throw re.rethrowFromSystemServer();
             }
+            final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller(
+                    Binder.getCallingUid());
             final long token = Binder.clearCallingIdentity();
             try {
                 return UsageStatsService.this.isAppIdleFilteredOrParoled(packageName, userId,
-                        SystemClock.elapsedRealtime());
+                        SystemClock.elapsedRealtime(), obfuscateInstantApps);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -1647,9 +1692,10 @@
 
         @Override
         public List<UsageStats> queryUsageStatsForUser(
-                int userId, int intervalType, long beginTime, long endTime) {
+                int userId, int intervalType, long beginTime, long endTime,
+                boolean obfuscateInstantApps) {
             return UsageStatsService.this.queryUsageStats(
-                    userId, intervalType, beginTime, endTime);
+                    userId, intervalType, beginTime, endTime, obfuscateInstantApps);
         }
     }
 }
diff --git a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
index 96f3305..cc53a9c 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
@@ -26,7 +26,10 @@
 import android.app.usage.UsageEvents;
 import android.app.usage.UsageStats;
 import android.content.res.Configuration;
+import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.Log;
+import android.util.LogWriter;
 
 import java.io.IOException;
 import java.net.ProtocolException;
@@ -35,6 +38,8 @@
  * UsageStats reader/writer for version 1 of the XML format.
  */
 final class UsageStatsXmlV1 {
+    private static final String TAG = "UsageStatsXmlV1";
+
     private static final String PACKAGES_TAG = "packages";
     private static final String PACKAGE_TAG = "package";
 
@@ -51,6 +56,7 @@
 
     // Attributes
     private static final String PACKAGE_ATTR = "package";
+    private static final String FLAGS_ATTR = "flags";
     private static final String CLASS_ATTR = "class";
     private static final String TOTAL_TIME_ACTIVE_ATTR = "timeActive";
     private static final String COUNT_ATTR = "count";
@@ -70,7 +76,6 @@
         if (pkg == null) {
             throw new ProtocolException("no " + PACKAGE_ATTR + " attribute present");
         }
-
         final UsageStats stats = statsOut.getOrCreateUsageStats(pkg);
 
         // Apply the offset to the beginTime to find the absolute time.
@@ -149,11 +154,12 @@
         if (packageName == null) {
             throw new ProtocolException("no " + PACKAGE_ATTR + " attribute present");
         }
-
         final String className = XmlUtils.readStringAttribute(parser, CLASS_ATTR);
 
         final UsageEvents.Event event = statsOut.buildEvent(packageName, className);
 
+        event.mFlags = XmlUtils.readIntAttribute(parser, FLAGS_ATTR, 0);
+
         // Apply the offset to the beginTime to find the absolute time of this event.
         event.mTimeStamp = statsOut.beginTime + XmlUtils.readLongAttribute(parser, TIME_ATTR);
 
@@ -256,6 +262,7 @@
         if (event.mClass != null) {
             XmlUtils.writeStringAttribute(xml, CLASS_ATTR, event.mClass);
         }
+        XmlUtils.writeIntAttribute(xml, FLAGS_ATTR, event.mFlags);
         XmlUtils.writeIntAttribute(xml, TYPE_ATTR, event.mEventType);
 
         switch (event.mEventType) {
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 8d335a5..0abbb82 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -19,11 +19,8 @@
 import android.app.usage.ConfigurationStats;
 import android.app.usage.TimeSparseArray;
 import android.app.usage.UsageEvents;
-import android.app.usage.UsageEvents.Event;
 import android.app.usage.UsageStats;
 import android.app.usage.UsageStatsManager;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.os.SystemClock;
 import android.content.Context;
@@ -312,7 +309,8 @@
         return queryStats(bucketType, beginTime, endTime, sConfigStatsCombiner);
     }
 
-    UsageEvents queryEvents(final long beginTime, final long endTime) {
+    UsageEvents queryEvents(final long beginTime, final long endTime,
+            boolean obfuscateInstantApps) {
         final ArraySet<String> names = new ArraySet<>();
         List<UsageEvents.Event> results = queryStats(UsageStatsManager.INTERVAL_DAILY,
                 beginTime, endTime, new StatCombiner<UsageEvents.Event>() {
@@ -334,7 +332,10 @@
                                 return;
                             }
 
-                            final UsageEvents.Event event = stats.events.valueAt(i);
+                            UsageEvents.Event event = stats.events.valueAt(i);
+                            if (obfuscateInstantApps) {
+                                event = event.getObfuscatedIfInstantApp();
+                            }
                             names.add(event.mPackage);
                             if (event.mClass != null) {
                                 names.add(event.mClass);
@@ -586,6 +587,7 @@
             if (event.mShortcutId != null) {
                 pw.printPair("shortcutId", event.mShortcutId);
             }
+            pw.printHexPair("flags", event.mFlags);
             pw.println();
         }
         pw.decreaseIndent();
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 6dfd085..656240f 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -69,7 +69,6 @@
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Random;
 import java.util.Scanner;
 import java.util.Set;
 
@@ -589,7 +588,6 @@
                     oldFunctions = UsbManager.USB_FUNCTION_NONE;
                 }
 
-                Slog.i(TAG, "Setting adb to " + String.valueOf(enable));
                 setEnabledFunctions(oldFunctions, true, mUsbDataUnlocked);
                 updateAdbNotification(false);
             }
@@ -817,16 +815,15 @@
 
             // send broadcast intent only if the USB state has changed
             if (!isUsbStateChanged(intent) && !configChanged) {
-                Slog.i(TAG, "skip broadcasting " + intent + " extras: " + intent.getExtras());
+                if (DEBUG) {
+                    Slog.d(TAG, "skip broadcasting " + intent + " extras: " + intent.getExtras());
+                }
                 return;
             }
-            mBroadcastedIntent = intent;
 
-            Random rand = new Random();
-            intent.putExtra("random_tag", rand.nextInt(1000));
-            Slog.i(TAG, "broadcasting " + intent + " extras: " + intent.getExtras());
+            if (DEBUG) Slog.d(TAG, "broadcasting " + intent + " extras: " + intent.getExtras());
             mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-            intent.removeExtra("random_tag");
+            mBroadcastedIntent = intent;
         }
 
         private void updateUsbFunctions() {
@@ -895,7 +892,6 @@
                     updateUsbNotification(false);
                     updateAdbNotification(false);
                     if (mBootCompleted) {
-                        Slog.i(TAG, "update state " + mConnected + " " + mConfigured);
                         updateUsbStateBroadcastIfNeeded(false);
                     }
                     if (UsbManager.containsFunction(mCurrentFunctions,
@@ -905,7 +901,6 @@
                     if (mBootCompleted) {
                         if (!mConnected) {
                             // restore defaults when USB is disconnected
-                            Slog.i(TAG, "Disconnect, setting usb functions to null");
                             setEnabledFunctions(null, !mAdbEnabled, false);
                         }
                         updateUsbFunctions();
@@ -992,7 +987,6 @@
                     break;
                 case MSG_SET_CURRENT_FUNCTIONS:
                     String functions = (String) msg.obj;
-                    Slog.i(TAG, "Getting setFunction command for " + functions);
                     setEnabledFunctions(functions, false, msg.arg1 == 1);
                     break;
                 case MSG_UPDATE_USER_RESTRICTIONS:
@@ -1000,8 +994,6 @@
                     final boolean forceRestart = mUsbDataUnlocked
                             && isUsbDataTransferActive()
                             && !isUsbTransferAllowed();
-                    Slog.i(TAG, "Updating user restrictions, force restart is "
-                            + String.valueOf(forceRestart));
                     setEnabledFunctions(
                             mCurrentFunctions, forceRestart, mUsbDataUnlocked && !forceRestart);
                     break;
@@ -1020,7 +1012,6 @@
                         updateUsbStateBroadcastIfNeeded(false);
                         mPendingBootBroadcast = false;
                     }
-                    Slog.i(TAG, "Boot complete, setting default functions");
                     setEnabledFunctions(null, false, false);
                     if (mCurrentAccessory != null) {
                         getCurrentSettings().accessoryAttached(mCurrentAccessory);
@@ -1038,7 +1029,6 @@
                             Slog.v(TAG, "Current user switched to " + msg.arg1
                                     + "; resetting USB host stack for MTP or PTP");
                             // avoid leaking sensitive data from previous user
-                            Slog.i(TAG, "User Switched, kicking usb stack");
                             setEnabledFunctions(mCurrentFunctions, true, false);
                         }
                         mCurrentUser = msg.arg1;
diff --git a/telephony/java/android/telephony/ImsiEncryptionInfo.aidl b/telephony/java/android/telephony/ImsiEncryptionInfo.aidl
new file mode 100644
index 0000000..080e30a
--- /dev/null
+++ b/telephony/java/android/telephony/ImsiEncryptionInfo.aidl
@@ -0,0 +1,19 @@
+/*
+* Copyright (C) 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.
+*/
+
+package android.telephony;
+
+parcelable ImsiEncryptionInfo;
diff --git a/telephony/java/android/telephony/ImsiEncryptionInfo.java b/telephony/java/android/telephony/ImsiEncryptionInfo.java
new file mode 100644
index 0000000..ecb9d25
--- /dev/null
+++ b/telephony/java/android/telephony/ImsiEncryptionInfo.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 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.
+ */
+package android.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+
+/**
+ * Class to represent information sent by the carrier, which will be used to encrypt
+ * the IMSI + IMPI. The ecryption is being done by WLAN, and the modem.
+ *
+ * @hide
+ */
+public final class ImsiEncryptionInfo implements Parcelable {
+
+    private static final String LOG_TAG = "ImsiEncryptionInfo";
+    private static final boolean DBG = false;
+
+
+    private final String mcc;
+    private final String mnc;
+    private final PublicKey publicKey;
+    private final String keyIdentifier;
+    private final int keyType;
+
+    public ImsiEncryptionInfo(String mcc, String mnc, int keyType, String keyIdentifier,
+                              PublicKey publicKey) {
+        this.mcc = mcc;
+        this.mnc = mnc;
+        this.keyType = keyType;
+        this.publicKey = publicKey;
+        this.keyIdentifier = keyIdentifier;
+    }
+
+    public ImsiEncryptionInfo(Parcel in) {
+        int length = in.readInt();
+        byte b[] = new byte[length];
+        in.readByteArray(b);
+        publicKey = makeKeyObject(b);
+        mcc = in.readString();
+        mnc = in.readString();
+        keyIdentifier = in.readString();
+        keyType = in.readInt();
+
+    }
+
+    public String getMnc() {
+        return this.mnc;
+    }
+
+    public String getMcc() {
+        return this.mcc;
+    }
+
+    public String getKeyIdentifier() {
+        return this.keyIdentifier;
+    }
+
+    public int getKeyType() {
+        return this.keyType;
+    }
+
+    public PublicKey getPublicKey() {
+        return this.publicKey;
+    }
+
+    private static PublicKey makeKeyObject(byte[] publicKeyBytes) {
+        try {
+            X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(publicKeyBytes);
+            return KeyFactory.getInstance("RSA").generatePublic(pubKeySpec);
+        } catch (InvalidKeySpecException | NoSuchAlgorithmException ex) {
+            Log.e(LOG_TAG, "Error makeKeyObject: unable to convert into PublicKey", ex);
+        }
+     return null;
+    }
+
+    /** Implement the Parcelable interface */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<ImsiEncryptionInfo> CREATOR =
+            new Parcelable.Creator<ImsiEncryptionInfo>() {
+                @Override
+                public ImsiEncryptionInfo createFromParcel(Parcel in) {
+                    return new ImsiEncryptionInfo(in);
+                }
+
+                @Override
+                public ImsiEncryptionInfo[] newArray(int size) {
+                    return new ImsiEncryptionInfo[size];
+                }
+            };
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        byte[] b = publicKey.getEncoded();
+        dest.writeInt(b.length);
+        dest.writeByteArray(b);
+        dest.writeString(mcc);
+        dest.writeString(mnc);
+        dest.writeString(keyIdentifier);
+        dest.writeInt(keyType);
+    }
+
+    @Override
+    public String toString(){
+        return "[ImsiEncryptionInfo "
+                + "mcc=" + mcc
+                + "mnc=" + mnc
+                + "publicKey=" + publicKey
+                + ", keyIdentifier=" + keyIdentifier
+                + ", keyType=" + keyType
+                + "]";
+    }
+}
diff --git a/telephony/java/android/telephony/MbmsStreamingManager.java b/telephony/java/android/telephony/MbmsStreamingManager.java
index 58262e1..6754426 100644
--- a/telephony/java/android/telephony/MbmsStreamingManager.java
+++ b/telephony/java/android/telephony/MbmsStreamingManager.java
@@ -22,12 +22,13 @@
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.os.DeadObjectException;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.telephony.mbms.IMbmsStreamingManagerCallback;
-import android.telephony.mbms.IStreamingServiceCallback;
 import android.telephony.mbms.MbmsException;
+import android.telephony.mbms.MbmsStreamingManagerCallback;
 import android.telephony.mbms.StreamingService;
+import android.telephony.mbms.StreamingServiceCallback;
 import android.telephony.mbms.StreamingServiceInfo;
 import android.telephony.mbms.vendor.IMbmsStreamingService;
 import android.util.Log;
@@ -77,14 +78,14 @@
     };
     private List<ServiceListener> mServiceListeners = new LinkedList<>();
 
-    private IMbmsStreamingManagerCallback mCallbackToApp;
+    private MbmsStreamingManagerCallback mCallbackToApp;
     private final String mAppName;
 
     private final Context mContext;
     private int mSubscriptionId = INVALID_SUBSCRIPTION_ID;
 
     /** @hide */
-    private MbmsStreamingManager(Context context, IMbmsStreamingManagerCallback listener,
+    private MbmsStreamingManager(Context context, MbmsStreamingManagerCallback listener,
                     String streamingAppName, int subscriptionId) {
         mContext = context;
         mAppName = streamingAppName;
@@ -106,7 +107,7 @@
      * @param subscriptionId The subscription ID to use.
      */
     public static MbmsStreamingManager create(Context context,
-            IMbmsStreamingManagerCallback listener, String streamingAppName, int subscriptionId)
+            MbmsStreamingManagerCallback listener, String streamingAppName, int subscriptionId)
             throws MbmsException {
         MbmsStreamingManager manager = new MbmsStreamingManager(context, listener,
                 streamingAppName, subscriptionId);
@@ -116,10 +117,10 @@
 
     /**
      * Create a new MbmsStreamingManager using the system default data subscription ID.
-     * See {@link #create(Context, IMbmsStreamingManagerCallback, String, int)}.
+     * See {@link #create(Context, MbmsStreamingManagerCallback, String, int)}.
      */
     public static MbmsStreamingManager create(Context context,
-            IMbmsStreamingManagerCallback listener, String streamingAppName)
+            MbmsStreamingManagerCallback listener, String streamingAppName)
             throws MbmsException {
         int subId = SubscriptionManager.getDefaultSubscriptionId();
         MbmsStreamingManager manager = new MbmsStreamingManager(context, listener,
@@ -155,13 +156,13 @@
      *
      * This may throw an {@link MbmsException} containing one of the following errors:
      * {@link MbmsException#ERROR_MIDDLEWARE_NOT_BOUND}
-     * {@link MbmsException#ERROR_NOT_YET_INITIALIZED}
+     * {@link MbmsException#ERROR_UNKNOWN_REMOTE_EXCEPTION}
      * {@link MbmsException#ERROR_CONCURRENT_SERVICE_LIMIT_REACHED}
+     * {@link MbmsException#ERROR_SERVICE_LOST}
      *
-     * Asynchronous error codes via the {@link IMbmsStreamingManagerCallback#error(int, String)}
+     * Asynchronous error codes via the {@link MbmsStreamingManagerCallback#error(int, String)}
      * callback can include any of the errors except:
      * {@link MbmsException#ERROR_UNABLE_TO_START_SERVICE}
-     * {@link MbmsException#ERROR_INVALID_SERVICE_ID}
      * {@link MbmsException#ERROR_END_OF_SESSION}
      */
     public void getStreamingServices(List<String> classList) throws MbmsException {
@@ -173,6 +174,10 @@
             if (returnCode != MbmsException.SUCCESS) {
                 throw new MbmsException(returnCode);
             }
+        } catch (DeadObjectException e) {
+            Log.w(LOG_TAG, "Remote process died");
+            mService = null;
+            throw new MbmsException(MbmsException.ERROR_SERVICE_LOST);
         } catch (RemoteException e) {
             throw new MbmsException(MbmsException.ERROR_UNKNOWN_REMOTE_EXCEPTION);
         }
@@ -180,36 +185,42 @@
 
     /**
      * Starts streaming a requested service, reporting status to the indicated listener.
-     * Returns an object used to control that stream.
+     * Returns an object used to control that stream. The stream may not be ready for consumption
+     * immediately upon return from this method -- wait until the streaming state has been
+     * reported via {@link android.telephony.mbms.StreamingServiceCallback#streamStateChanged(int)}.
      *
-     * May throw an IllegalArgumentException or RemoteException.
+     * May throw an {@link MbmsException} containing any of the following error codes:
+     * {@link MbmsException#ERROR_MIDDLEWARE_NOT_BOUND}
+     * {@link MbmsException#ERROR_UNKNOWN_REMOTE_EXCEPTION}
+     * {@link MbmsException#ERROR_CONCURRENT_SERVICE_LIMIT_REACHED}
+     * {@link MbmsException#ERROR_SERVICE_LOST}
+     *
+     * May also throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
      *
      * Asynchronous errors through the listener include any of the errors
      */
     public StreamingService startStreaming(StreamingServiceInfo serviceInfo,
-            IStreamingServiceCallback listener) {
-        return null;
-    }
+            StreamingServiceCallback listener) throws MbmsException {
+        if (mService == null) {
+            throw new MbmsException(MbmsException.ERROR_MIDDLEWARE_NOT_BOUND);
+        }
 
-    /**
-     * Lists all the services currently being streamed to the device by this application
-     * on this given subId.  Results are returned asynchronously through the previously
-     * registered callback.
-     *
-     * May throw a RemoteException.
-     *
-     * The return value is a success/error-code with the following possible values:
-     * <li>SUCCESS</li>
-     * <li>ERROR_MSDC_CONCURRENT_SERVICE_LIMIT_REACHED</li>
-     *
-     * Asynchronous errors through the listener include any of the errors except
-     * <li>ERROR_UNABLED_TO_START_SERVICE</li>
-     * <li>ERROR_MSDC_INVALID_SERVICE_ID</li>
-     * <li>ERROR_MSDC_END_OF_SESSION</li>
-     *
-     */
-    public int getActiveStreamingServices() {
-        return 0;
+        try {
+            int returnCode = mService.startStreaming(
+                    mAppName, mSubscriptionId, serviceInfo.getServiceId(), listener);
+            if (returnCode != MbmsException.SUCCESS) {
+                throw new MbmsException(returnCode);
+            }
+        } catch (DeadObjectException e) {
+            Log.w(LOG_TAG, "Remote process died");
+            mService = null;
+            throw new MbmsException(MbmsException.ERROR_SERVICE_LOST);
+        } catch (RemoteException e) {
+            throw new MbmsException(MbmsException.ERROR_UNKNOWN_REMOTE_EXCEPTION);
+        }
+
+        return new StreamingService(
+                mAppName, mSubscriptionId, mService, serviceInfo, listener);
     }
 
     private void bindAndInitialize() throws MbmsException {
@@ -269,7 +280,11 @@
             } catch (RemoteException e) {
                 mService = null;
                 Log.e(LOG_TAG, "Service died before initialization");
-                throw new MbmsException(MbmsException.ERROR_UNKNOWN_REMOTE_EXCEPTION);
+                if (e instanceof DeadObjectException) {
+                    throw new MbmsException(MbmsException.ERROR_SERVICE_LOST);
+                } else {
+                    throw new MbmsException(MbmsException.ERROR_UNKNOWN_REMOTE_EXCEPTION);
+                }
             }
         }
     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c8ff08c..233a8d1 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -72,6 +72,11 @@
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -143,6 +148,12 @@
     static public final int OTASP_SIM_UNPROVISIONED = 5;
 
 
+    /** @hide */
+    static public final int KEY_TYPE_EPDDG = 1;
+
+    /** @hide */
+    static public final int KEY_TYPE_WLAN = 2;
+
     private final Context mContext;
     private final int mSubId;
     private SubscriptionManager mSubscriptionManager;
@@ -2334,6 +2345,73 @@
     }
 
     /**
+     * Returns Carrier specific information that will be used to encrypt the IMSI and IMPI.
+     * This includes the public key and the key identifier. For multi-sim devices, if no subId
+     * has been specified, we will return the value for the dafault data sim.
+     * Return null if it is unavailable.
+     * <p>
+     * Requires Permission:
+     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     * @param keyType whether the key is being used for wlan or epdg. Valid key types are
+     *        {@link TelephonyManager#KEY_TYPE_EPDDG} or
+     *        {@link TelephonyManager#KEY_TYPE_WLAN}.
+     * @return ImsiEncryptionInfo Carrier specific information that will be used to encrypt the
+     *         IMSI and IMPI. This includes the public key and the key identifier. This information
+     *         will be stored in the device keystore.
+     * @hide
+     */
+    public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType) {
+        try {
+            IPhoneSubInfo info = getSubscriberInfo();
+            if (info == null) return null;
+            int subId = getSubId(SubscriptionManager.getDefaultDataSubscriptionId());
+            if (keyType != KEY_TYPE_EPDDG && keyType != KEY_TYPE_WLAN) {
+                throw new IllegalArgumentException("Invalid key type");
+            }
+            return info.getCarrierInfoForImsiEncryption(subId, keyType,
+                    mContext.getOpPackageName());
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "getCarrierInfoForImsiEncryption RemoteException", ex);
+            return null;
+        } catch (NullPointerException ex) {
+            // This could happen before phone restarts due to crashing
+            Rlog.e(TAG, "getCarrierInfoForImsiEncryption NullPointerException", ex);
+            return null;
+        }
+    }
+
+    /**
+     * Sets the Carrier specific information that will be used to encrypt the IMSI and IMPI.
+     * This includes the public key and the key identifier. This information will be stored in the
+     * device keystore.
+     * <p>
+     * Requires Permission:
+     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     * @param imsiEncryptionInfo which includes the Key Type, the Public Key
+     *        (java.security.PublicKey) and the Key Identifier.and the Key Identifier.
+     *        The keyIdentifier Attribute value pair that helps a server locate
+     *        the private key to decrypt the permanent identity. This field is
+     *        optional and if it is present then it’s always separated from encrypted
+     *        permanent identity with “,”. Key identifier AVP is presented in ASCII string
+     *        with “name=value” format.
+     * @hide
+     */
+    public void setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo) {
+        try {
+            IPhoneSubInfo info = getSubscriberInfo();
+            if (info == null) return;
+            info.setCarrierInfoForImsiEncryption(mSubId, mContext.getOpPackageName(),
+                    imsiEncryptionInfo);
+        } catch (NullPointerException ex) {
+            // This could happen before phone restarts due to crashing
+            return;
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "setCarrierInfoForImsiEncryption RemoteException", ex);
+            return;
+        }
+    }
+
+    /**
      * Returns the Group Identifier Level1 for a GSM phone.
      * Return null if it is unavailable.
      */
diff --git a/telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl b/telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl
index 6d2e031..891edad 100755
--- a/telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl
+++ b/telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl
@@ -17,14 +17,13 @@
 package android.telephony.mbms;
 
 import android.net.Uri;
-import android.telephony.mbms.StreamingService;
 
 /**
  * @hide
  */
 oneway interface IStreamingServiceCallback {
     void error(int errorCode, String message);
-    void streamStateChanged(in StreamingService service, int state);
+    void streamStateChanged(int state);
     void uriUpdated(in Uri uri);
     void broadcastSignalStrengthUpdated(int signalStrength);
 }
diff --git a/telephony/java/android/telephony/mbms/MbmsException.java b/telephony/java/android/telephony/mbms/MbmsException.java
index e8680ea..ac14c4f 100644
--- a/telephony/java/android/telephony/mbms/MbmsException.java
+++ b/telephony/java/android/telephony/mbms/MbmsException.java
@@ -27,16 +27,15 @@
     public static final int ERROR_CONCURRENT_SERVICE_LIMIT_REACHED = 6;
     public static final int ERROR_MIDDLEWARE_NOT_BOUND = 7;
     public static final int ERROR_UNABLE_TO_START_SERVICE = 8;
-    public static final int ERROR_INVALID_SERVICE_ID = 9;
+    public static final int ERROR_STREAM_ALREADY_STARTED = 9;
     public static final int ERROR_END_OF_SESSION = 10;
-    public static final int ERROR_NOT_YET_INITIALIZED = 11;
-    public static final int ERROR_APP_PERMISSIONS_NOT_GRANTED = 12;
+    public static final int ERROR_SERVICE_LOST = 11;
 
     private final int mErrorCode;
 
     /** @hide
      * TODO: future systemapi
-     * */
+     */
     public MbmsException(int errorCode) {
         super();
         mErrorCode = errorCode;
diff --git a/telephony/java/android/telephony/mbms/StreamingService.aidl b/telephony/java/android/telephony/mbms/StreamingService.aidl
deleted file mode 100755
index 0c286f3..0000000
--- a/telephony/java/android/telephony/mbms/StreamingService.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-** 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.
-*/
-
-package android.telephony.mbms;
-
-parcelable StreamingService;
diff --git a/telephony/java/android/telephony/mbms/StreamingService.java b/telephony/java/android/telephony/mbms/StreamingService.java
index 08c4a27..745cb98 100644
--- a/telephony/java/android/telephony/mbms/StreamingService.java
+++ b/telephony/java/android/telephony/mbms/StreamingService.java
@@ -17,81 +17,112 @@
 package android.telephony.mbms;
 
 import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
+import android.os.DeadObjectException;
+import android.os.RemoteException;
+import android.telephony.mbms.vendor.IMbmsStreamingService;
+import android.util.Log;
 
 /**
  * @hide
  */
 public class StreamingService {
-
+    private static final String LOG_TAG = "MbmsStreamingService";
     public final static int STATE_STOPPED = 1;
     public final static int STATE_STARTED = 2;
     public final static int STATE_STALLED = 3;
 
+    private final String mAppName;
+    private final int mSubscriptionId;
+    private final StreamingServiceInfo mServiceInfo;
+    private final IStreamingServiceCallback mCallback;
+
+    private IMbmsStreamingService mService;
     /**
+     * @hide
      */
-    StreamingService(StreamingServiceInfo streamingServiceInfo,
-            IStreamingServiceCallback listener) {
+    public StreamingService(String appName,
+            int subscriptionId,
+            IMbmsStreamingService service,
+            StreamingServiceInfo streamingServiceInfo,
+            IStreamingServiceCallback callback) {
+        mAppName = appName;
+        mSubscriptionId = subscriptionId;
+        mService = service;
+        mServiceInfo = streamingServiceInfo;
+        mCallback = callback;
     }
 
     /**
      * Retreive the Uri used to play this stream.
      *
-     * This may throw a RemoteException.
+     * This may throw a {@link MbmsException} with the error codes
+     * {@link MbmsException#ERROR_UNKNOWN_REMOTE_EXCEPTION} or
+     * {@link MbmsException#ERROR_SERVICE_LOST}
+     *
+     * @return The {@link Uri} to pass to the streaming client.
      */
-    public Uri getPlaybackUri() {
-        return null;
+    public Uri getPlaybackUri() throws MbmsException {
+        if (mService == null) {
+            throw new IllegalStateException("No streaming service attached");
+        }
+
+        try {
+            return mService.getPlaybackUri(mAppName, mSubscriptionId, mServiceInfo.getServiceId());
+        } catch (DeadObjectException e) {
+            Log.w(LOG_TAG, "Remote process died");
+            mService = null;
+            throw new MbmsException(MbmsException.ERROR_SERVICE_LOST);
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "Caught remote exception calling getPlaybackUri: " + e);
+            throw new MbmsException(MbmsException.ERROR_UNKNOWN_REMOTE_EXCEPTION);
+        }
     }
 
     /**
      * Retreive the info for this StreamingService.
      */
     public StreamingServiceInfo getInfo() {
-        return null;
+        return mServiceInfo;
     }
 
     /**
-     * Retreive the current state of this stream.
-     *
-     * This may throw a RemoteException.
+     * Stop streaming this service.
+     * This may throw a {@link MbmsException} with the error code
+     * {@link MbmsException#ERROR_UNKNOWN_REMOTE_EXCEPTION} or
+     * {@link MbmsException#ERROR_SERVICE_LOST}
      */
-    public int getState() {
-        return STATE_STOPPED;
-    }
-
-    /**
-     * Stop streaming this service.  Terminal.
-     *
-     * This may throw a RemoteException.
-     */
-    public void stopStreaming() {
-    }
-
-    public void dispose() {
-    }
-
-    public static final Parcelable.Creator<StreamingService> CREATOR =
-            new Parcelable.Creator<StreamingService>() {
-        @Override
-        public StreamingService createFromParcel(Parcel in) {
-            return new StreamingService(in);
+    public void stopStreaming() throws MbmsException {
+        if (mService == null) {
+            throw new IllegalStateException("No streaming service attached");
         }
 
-        @Override
-        public StreamingService[] newArray(int size) {
-            return new StreamingService[size];
+        try {
+            mService.stopStreaming(mAppName, mSubscriptionId, mServiceInfo.getServiceId());
+        } catch (DeadObjectException e) {
+            Log.w(LOG_TAG, "Remote process died");
+            mService = null;
+            throw new MbmsException(MbmsException.ERROR_SERVICE_LOST);
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "Caught remote exception calling stopStreaming: " + e);
+            throw new MbmsException(MbmsException.ERROR_UNKNOWN_REMOTE_EXCEPTION);
         }
-    };
-
-    private StreamingService(Parcel in) {
     }
 
-    public void writeToParcel(Parcel dest, int flags) {
-    }
+    public void dispose() throws MbmsException {
+        if (mService == null) {
+            throw new IllegalStateException("No streaming service attached");
+        }
 
-    public int describeContents() {
-        return 0;
+        try {
+            mService.disposeStream(mAppName, mSubscriptionId, mServiceInfo.getServiceId());
+        } catch (DeadObjectException e) {
+            Log.w(LOG_TAG, "Remote process died");
+            mService = null;
+            throw new MbmsException(MbmsException.ERROR_SERVICE_LOST);
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "Caught remote exception calling dispose: " + e);
+            throw new MbmsException(MbmsException.ERROR_UNKNOWN_REMOTE_EXCEPTION);
+        }
     }
 }
 
diff --git a/telephony/java/android/telephony/mbms/StreamingServiceCallback.java b/telephony/java/android/telephony/mbms/StreamingServiceCallback.java
index 752a4b3..bd0a1b3 100644
--- a/telephony/java/android/telephony/mbms/StreamingServiceCallback.java
+++ b/telephony/java/android/telephony/mbms/StreamingServiceCallback.java
@@ -19,7 +19,7 @@
 import android.net.Uri;
 
 /**
- * A Callback class for use when the applicaiton is actively streaming content.
+ * A Callback class for use when the application is actively streaming content.
  * @hide
  */
 public class StreamingServiceCallback extends IStreamingServiceCallback.Stub {
@@ -33,7 +33,6 @@
      */
     public static final int SIGNAL_STRENGTH_UNAVAILABLE = -1;
 
-
     public void error(int errorCode, String message) {
         // default implementation empty
     }
@@ -44,7 +43,7 @@
      * See {@link StreamingService#STATE_STOPPED}, {@link StreamingService#STATE_STARTED}
      * and {@link StreamingService#STATE_STALLED}.
      */
-    public void streamStateChanged(StreamingService service, int state) {
+    public void streamStateChanged(int state) {
         // default implementation empty
     }
 
diff --git a/telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl b/telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl
index a77a10a..8ff7fa7 100755
--- a/telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl
+++ b/telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl
@@ -19,7 +19,6 @@
 import android.net.Uri;
 import android.telephony.mbms.IMbmsStreamingManagerCallback;
 import android.telephony.mbms.IStreamingServiceCallback;
-import android.telephony.mbms.StreamingService;
 import android.telephony.mbms.StreamingServiceInfo;
 
 /**
@@ -32,35 +31,19 @@
 
     int getStreamingServices(String appName, int subId, in List<String> serviceClasses);
 
-    /**
-     * - Starts streaming the serviceId given.
-     * - if the uid/appName/subId don't match a previously registered callback an error will
-     *   be returned
-     * - Streaming status will be sent via the included listener, including an initial
-     *   URL-change and State-change pair.
-     */
     int startStreaming(String appName, int subId, String serviceId,
             IStreamingServiceCallback listener);
 
     /**
-     * Asynchronously fetches all Services being streamed by this uid/appName/subId.
-     */
-    int getActiveStreamingServices(String appName, int subId);
-
-
-    /**
      * Per-stream api.  Note each specifies what stream they apply to.
      */
 
     Uri getPlaybackUri(String appName, int subId, String serviceId);
 
-    int getState(String appName, int subId, String serviceId);
-
     void stopStreaming(String appName, int subId, String serviceId);
 
     void disposeStream(String appName, int subId, String serviceId);
 
-
     /**
      * End of life for all MbmsStreamingManager's created by this uid/appName/subId.
      * Ends any streams run under this uid/appname/subId and calls the disposed methods
diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
index 4670352..5b74312 100644
--- a/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
+++ b/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java
@@ -16,6 +16,7 @@
 
 package android.telephony.mbms.vendor;
 
+import android.annotation.Nullable;
 import android.net.Uri;
 import android.os.RemoteException;
 import android.telephony.mbms.IMbmsStreamingManagerCallback;
@@ -32,11 +33,12 @@
     /**
      * Initialize streaming service for this app and subId, registering the listener.
      *
+     * May throw an {@link IllegalArgumentException} or a {@link SecurityException}
+     *
      * @param listener The callback to use to communicate with the app.
      * @param appName The app name as negotiated with the wireless carrier.
      * @param subscriptionId The subscription ID to use.
-     * @return {@link MbmsException#SUCCESS}, {@link MbmsException#ERROR_ALREADY_INITIALIZED}, or
-     *         {@link MbmsException#ERROR_APP_PERMISSIONS_NOT_GRANTED}
+     * @return {@link MbmsException#SUCCESS} or {@link MbmsException#ERROR_ALREADY_INITIALIZED}
      */
     @Override
     public int initialize(IMbmsStreamingManagerCallback listener, String appName,
@@ -52,6 +54,8 @@
      * Note that subsequent calls with the same uid, appName and subId will replace
      * the service class list.
      *
+     * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
+     *
      * @param appName The app name as negotiated with the wireless carrier.
      * @param subscriptionId The subscription id to use.
      * @param serviceClasses The service classes that the app wishes to get info on. The strings
@@ -59,7 +63,6 @@
      *                       carrier.
      * @return One of {@link MbmsException#SUCCESS},
      *         {@link MbmsException#ERROR_MIDDLEWARE_NOT_BOUND},
-     *         {@link MbmsException#ERROR_NOT_YET_INITIALIZED}, or
      *         {@link MbmsException#ERROR_CONCURRENT_SERVICE_LIMIT_REACHED}
      */
     @Override
@@ -68,36 +71,80 @@
         return 0;
     }
 
+    /**
+     * Starts streaming on a particular service. This method may perform asynchronous work. When
+     * the middleware is ready to send bits to the frontend, it should inform the app via
+     * {@link IStreamingServiceCallback#streamStateChanged(int)}.
+     *
+     * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
+     *
+     * @param appName The app name as negotiated with the wireless carrier.
+     * @param subscriptionId The subscription id to use.
+     * @param serviceId The ID of the streaming service that the app has requested.
+     * @param listener The listener object on which the app wishes to receive updates.
+     * @return TODO: document possible errors
+     */
     @Override
-    public int startStreaming(String appName, int subId,
+    public int startStreaming(String appName, int subscriptionId,
             String serviceId, IStreamingServiceCallback listener) throws RemoteException {
         return 0;
     }
 
+    /**
+     * Retrieves the streaming URI for a particular service. If the middleware is not yet ready to
+     * stream the service, this method may return null.
+     *
+     * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
+     *
+     * @param appName The app name as negotiated with the wireless carrier.
+     * @param subscriptionId The subscription id to use.
+     * @param serviceId The ID of the streaming service that the app has requested.
+     * @return An opaque {@link Uri} to be passed to a video player that understands the format.
+     */
     @Override
-    public int getActiveStreamingServices(String appName, int subId) throws RemoteException {
-        return 0;
-    }
-
-    @Override
-    public Uri getPlaybackUri(String appName, int subId, String serviceId) throws RemoteException {
+    public @Nullable Uri getPlaybackUri(String appName, int subscriptionId, String serviceId)
+            throws RemoteException {
         return null;
     }
 
+    /**
+     * Stop streaming the stream identified by {@code serviceId}. Notification of the resulting
+     * stream state change should be reported to the app via
+     * {@link IStreamingServiceCallback#streamStateChanged(int)}.
+     * @param appName The app name as negotiated with the wireless carrier.
+     * @param subscriptionId The subscription id to use.
+     * @param serviceId The ID of the streaming service that the app wishes to stop.
+     */
     @Override
-    public int getState(String appName, int subId, String serviceId) throws RemoteException {
-        return 0;
+    public void stopStreaming(String appName, int subscriptionId, String serviceId)
+            throws RemoteException {
     }
 
+    /**
+     * Dispose of the stream identified by {@code serviceId} for the app identified by the
+     * {@code appName} and {@code subscriptionId} arguments along with the caller's uid.
+     * No notification back to the app is required for this operation, and the callback provided via
+     * {@link #startStreaming(String, int, String, IStreamingServiceCallback)} should no longer be
+     * used after this method has called by the app.
+     * @param appName The app name as negotiated with the wireless carrier.
+     * @param subscriptionId The subscription id to use.
+     * @param serviceId The ID of the streaming service that the app wishes to dispose of.
+     */
     @Override
-    public void stopStreaming(String appName, int subId, String serviceId) throws RemoteException {
+    public void disposeStream(String appName, int subscriptionId, String serviceId)
+            throws RemoteException {
     }
 
+    /**
+     * Signals that the app wishes to dispose of the session identified by the {@code appName} and
+     * {@code subscriptionId} arguments, as well as the caller's uid. No notification back to the
+     * app is required for this operation, and the corresponding callback provided via
+     * {@link #initialize(IMbmsStreamingManagerCallback, String, int)} should no longer be used
+     * after this method has been called by the app.
+     * @param appName The app name as negotiated with the wireless carrier.
+     * @param subscriptionId The subscription id to use.
+     */
     @Override
-    public void disposeStream(String appName, int subId, String serviceId) throws RemoteException {
-    }
-
-    @Override
-    public void dispose(String appName, int subId) throws RemoteException {
+    public void dispose(String appName, int subscriptionId) throws RemoteException {
     }
 }
diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
index 02baa34..dbd8867 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import android.telephony.ImsiEncryptionInfo;
+
 /**
  * Interface used to retrieve various phone-related subscriber information.
  *
@@ -138,6 +140,18 @@
     String getCompleteVoiceMailNumberForSubscriber(int subId);
 
     /**
+     * Retrieves the Carrier information used to encrypt IMSI and IMPI.
+     */
+    ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int subId, int keyType,
+    String callingPackage);
+
+    /**
+     * Stores the Carrier information used to encrypt IMSI and IMPI.
+     */
+    void setCarrierInfoForImsiEncryption(int subId, String callingPackage,
+    in ImsiEncryptionInfo imsiEncryptionInfo);
+
+    /**
      * Retrieves the alpha identifier associated with the voice mail number.
      */
     String getVoiceMailAlphaTag(String callingPackage);
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 8a5fd4b..272653f 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -111,7 +111,6 @@
 
 
     private Map<String, Intent> mNameToIntent;
-    private Map<String, String> mNameToProcess;
     private List<LaunchOrder> mLaunchOrderList = new ArrayList<LaunchOrder>();
     private Map<String, String> mNameToResultKey;
     private Map<String, List<Long>> mNameToLaunchTime;
@@ -431,7 +430,6 @@
 
     private void createMappings() {
         mNameToIntent = new LinkedHashMap<String, Intent>();
-        mNameToProcess = new LinkedHashMap<String, String>();
 
         PackageManager pm = getInstrumentation().getContext()
                 .getPackageManager();
@@ -459,8 +457,9 @@
                         ri.activityInfo.name);
                 String appName = ri.loadLabel(pm).toString();
                 if (appName != null) {
+                    // Support launching intent using package name or app name
+                    mNameToIntent.put(ri.activityInfo.packageName, startIntent);
                     mNameToIntent.put(appName, startIntent);
-                    mNameToProcess.put(appName, ri.activityInfo.processName);
                 }
             }
         }
diff --git a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/MainActivity.java b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/MainActivity.java
index db45b9d..99d44e6 100644
--- a/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/MainActivity.java
+++ b/tests/MusicServiceDemo/src/com/example/android/musicservicedemo/MainActivity.java
@@ -17,7 +17,7 @@
 
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
-import android.support.v7.app.ActionBarActivity;
+import android.support.v7.app.AppCompatActivity;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -31,7 +31,7 @@
 /**
  * Main activity of the app.
  */
-public class MainActivity extends ActionBarActivity {
+public class MainActivity extends AppCompatActivity {
 
     private static final String LOG = "MainActivity";
 
diff --git a/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java b/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java
index 7632a6e..55440c8 100644
--- a/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java
+++ b/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java
@@ -21,7 +21,7 @@
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.os.CountDownTimer;
-import android.support.v7.app.ActionBarActivity;
+import android.support.v7.app.AppCompatActivity;
 import android.os.Bundle;
 import android.text.method.Touch;
 import android.util.AttributeSet;
@@ -173,7 +173,7 @@
     private float mVelocityX, mVelocityY;
 }
 
-public class TouchLatencyActivity extends ActionBarActivity {
+public class TouchLatencyActivity extends AppCompatActivity {
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
diff --git a/tests/UsageStatsTest/Android.mk b/tests/UsageStatsTest/Android.mk
index 5f7467a..6b5c999 100644
--- a/tests/UsageStatsTest/Android.mk
+++ b/tests/UsageStatsTest/Android.mk
@@ -8,6 +8,8 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
 
+LOCAL_CERTIFICATE := platform
+
 LOCAL_PACKAGE_NAME := UsageStatsTest
 
 include $(BUILD_PACKAGE)
diff --git a/tests/UsageStatsTest/AndroidManifest.xml b/tests/UsageStatsTest/AndroidManifest.xml
index 589674a..c27be7b 100644
--- a/tests/UsageStatsTest/AndroidManifest.xml
+++ b/tests/UsageStatsTest/AndroidManifest.xml
@@ -1,7 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 
+<!--
+  Note: Add android:sharedUserId="android.uid.system" to the root element to simulate the system UID
+  caller case.
+-->
+
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.tests.usagestats">
+    package="com.android.tests.usagestats"
+    >
 
     <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
 
diff --git a/tests/UsageStatsTest/res/menu/main.xml b/tests/UsageStatsTest/res/menu/main.xml
index e781058..4ccbc81 100644
--- a/tests/UsageStatsTest/res/menu/main.xml
+++ b/tests/UsageStatsTest/res/menu/main.xml
@@ -2,4 +2,6 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:id="@+id/log"
         android:title="View Log"/>
+    <item android:id="@+id/call_is_app_inactive"
+        android:title="Call isAppInactive()"/>
 </menu>
diff --git a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageStatsActivity.java b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageStatsActivity.java
index c08c1a3..9429d9b 100644
--- a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageStatsActivity.java
+++ b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageStatsActivity.java
@@ -16,12 +16,16 @@
 
 package com.android.tests.usagestats;
 
+import android.app.AlertDialog;
 import android.app.ListActivity;
 import android.app.usage.UsageStats;
 import android.app.usage.UsageStatsManager;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.os.Bundle;
+import android.text.InputType;
+import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -30,6 +34,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.BaseAdapter;
+import android.widget.EditText;
 import android.widget.TextView;
 
 import java.util.ArrayList;
@@ -69,6 +74,9 @@
             case R.id.log:
                 startActivity(new Intent(this, UsageLogActivity.class));
                 return true;
+            case R.id.call_is_app_inactive:
+                callIsAppInactive();
+                return true;
 
             default:
                 return super.onOptionsItemSelected(item);
@@ -81,6 +89,41 @@
         updateAdapter();
     }
 
+    private void callIsAppInactive() {
+        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
+        builder.setTitle("Enter package name");
+        final EditText input = new EditText(this);
+        input.setInputType(InputType.TYPE_CLASS_TEXT);
+        input.setHint("com.android.tests.usagestats");
+        builder.setView(input);
+
+        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                final String packageName = input.getText().toString().trim();
+                if (!TextUtils.isEmpty(packageName)) {
+                    showInactive(packageName);
+                }
+            }
+        });
+        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                dialog.cancel();
+            }
+        });
+
+        builder.show();
+    }
+
+    private void showInactive(String packageName) {
+        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
+        builder.setMessage(
+                "isAppInactive(\"" + packageName + "\") = "
+                        + (mUsageStatsManager.isAppInactive(packageName) ? "true" : "false"));
+        builder.show();
+    }
+
     private void updateAdapter() {
         long now = System.currentTimeMillis();
         long beginTime = now - USAGE_STATS_PERIOD;
diff --git a/tests/net/java/android/net/util/SharedLogTest.java b/tests/net/java/android/net/util/SharedLogTest.java
new file mode 100644
index 0000000..7fd7a63
--- /dev/null
+++ b/tests/net/java/android/net/util/SharedLogTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package android.net.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Vector;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class SharedLogTest {
+    private static final String TIMESTAMP_PATTERN =
+            "^[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]";
+    private static final String TIMESTAMP = "mm-dd HH:MM:SS.xxx";
+
+    @Test
+    public void testBasicOperation() {
+        final SharedLog logTop = new SharedLog("top");
+        logTop.mark("first post!");
+
+        final SharedLog logLevel2a = logTop.forSubComponent("twoA");
+        final SharedLog logLevel2b = logTop.forSubComponent("twoB");
+        logLevel2b.e("2b or not 2b");
+        logLevel2a.w("second post?");
+
+        final SharedLog logLevel3 = logLevel2a.forSubComponent("three");
+        logTop.log("still logging");
+        logLevel3.log("3 >> 2");
+        logLevel2a.mark("ok: last post");
+
+        final String[] expected = {
+            TIMESTAMP + " - MARK first post!",
+            TIMESTAMP + " - [twoB] ERROR 2b or not 2b",
+            TIMESTAMP + " - [twoA] WARN second post?",
+            TIMESTAMP + " - still logging",
+            TIMESTAMP + " - [twoA.three] 3 >> 2",
+            TIMESTAMP + " - [twoA] MARK ok: last post",
+        };
+        // Verify the logs are all there and in the correct order.
+        verifyLogLines(expected, logTop);
+
+        // In fact, because they all share the same underlying LocalLog,
+        // every subcomponent SharedLog's dump() is identical.
+        verifyLogLines(expected, logLevel2a);
+        verifyLogLines(expected, logLevel2b);
+        verifyLogLines(expected, logLevel3);
+    }
+
+    private static void verifyLogLines(String[] expected, SharedLog log) {
+        final ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+        final PrintWriter pw = new PrintWriter(ostream, true);
+        log.dump(null, pw, null);
+
+        final String dumpOutput = ostream.toString();
+        assertTrue(dumpOutput != null);
+        assertTrue(!"".equals(dumpOutput));
+
+        final String[] lines = dumpOutput.split("\n");
+        assertEquals(expected.length, lines.length);
+
+        for (int i = 0; i < lines.length; i++) {
+            // Fix up the timestamps.
+            lines[i] = lines[i].replaceAll(TIMESTAMP_PATTERN, TIMESTAMP);
+        }
+
+        for (int i = 0; i < expected.length; i++) {
+            assertEquals(expected[i], lines[i]);
+        }
+    }
+}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 0099861..e8a87c7 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -362,6 +362,10 @@
             mNetworkAgent.sendNetworkScore(mScore);
         }
 
+        public void explicitlySelected(boolean acceptUnvalidated) {
+            mNetworkAgent.explicitlySelected(acceptUnvalidated);
+        }
+
         public void addCapability(int capability) {
             mNetworkCapabilities.addCapability(capability);
             mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
@@ -797,6 +801,7 @@
 
         // Ensure that the default setting for Captive Portals is used for most tests
         setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
+        setMobileDataAlwaysOn(false);
     }
 
     public void tearDown() throws Exception {
@@ -1595,13 +1600,104 @@
         final int lingerTimeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4;
         callback.expectCallback(CallbackState.LOST, mCellNetworkAgent, lingerTimeoutMs);
 
+        // Register a TRACK_DEFAULT request and check that it does not affect lingering.
+        TestNetworkCallback trackDefaultCallback = new TestNetworkCallback();
+        mCm.registerDefaultNetworkCallback(trackDefaultCallback);
+        trackDefaultCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
+        mEthernetNetworkAgent = new MockNetworkAgent(TRANSPORT_ETHERNET);
+        mEthernetNetworkAgent.connect(true);
+        callback.expectAvailableCallbacks(mEthernetNetworkAgent);
+        callback.expectCallback(CallbackState.LOSING, mWiFiNetworkAgent);
+        callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent);
+        trackDefaultCallback.expectAvailableAndValidatedCallbacks(mEthernetNetworkAgent);
+        defaultCallback.expectAvailableAndValidatedCallbacks(mEthernetNetworkAgent);
+
+        // Let linger run its course.
+        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent, lingerTimeoutMs);
+
         // Clean up.
-        mWiFiNetworkAgent.disconnect();
-        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        mEthernetNetworkAgent.disconnect();
+        callback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
+        defaultCallback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
+        trackDefaultCallback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
 
         mCm.unregisterNetworkCallback(callback);
         mCm.unregisterNetworkCallback(defaultCallback);
+        mCm.unregisterNetworkCallback(trackDefaultCallback);
+    }
+
+    @SmallTest
+    public void testExplicitlySelected() {
+        NetworkRequest request = new NetworkRequest.Builder()
+                .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET)
+                .build();
+        TestNetworkCallback callback = new TestNetworkCallback();
+        mCm.registerNetworkCallback(request, callback);
+
+        // Bring up validated cell.
+        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+        mCellNetworkAgent.connect(true);
+        callback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
+
+        // Bring up unvalidated wifi with explicitlySelected=true.
+        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.explicitlySelected(false);
+        mWiFiNetworkAgent.connect(false);
+        callback.expectAvailableCallbacks(mWiFiNetworkAgent);
+
+        // Cell Remains the default.
+        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+
+        // Lower wifi's score to below than cell, and check that it doesn't disconnect because
+        // it's explicitly selected.
+        mWiFiNetworkAgent.adjustScore(-40);
+        mWiFiNetworkAgent.adjustScore(40);
+        callback.assertNoCallback();
+
+        // If the user chooses yes on the "No Internet access, stay connected?" dialog, we switch to
+        // wifi even though it's unvalidated.
+        mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), true, false);
+        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+
+        // Disconnect wifi, and then reconnect, again with explicitlySelected=true.
+        mWiFiNetworkAgent.disconnect();
+        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.explicitlySelected(false);
+        mWiFiNetworkAgent.connect(false);
+        callback.expectAvailableCallbacks(mWiFiNetworkAgent);
+
+        // If the user chooses no on the "No Internet access, stay connected?" dialog, we ask the
+        // network to disconnect.
+        mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), false, false);
+        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+
+        // Reconnect, again with explicitlySelected=true, but this time validate.
+        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.explicitlySelected(false);
+        mWiFiNetworkAgent.connect(true);
+        callback.expectAvailableCallbacks(mWiFiNetworkAgent);
+        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+        assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+
+        // BUG: the network will no longer linger, even though it's validated and outscored.
+        // TODO: fix this.
+        mEthernetNetworkAgent = new MockNetworkAgent(TRANSPORT_ETHERNET);
+        mEthernetNetworkAgent.connect(true);
+        callback.expectAvailableAndValidatedCallbacks(mEthernetNetworkAgent);
+        assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+        callback.assertNoCallback();
+
+        // Clean up.
+        mWiFiNetworkAgent.disconnect();
+        mCellNetworkAgent.disconnect();
+        mEthernetNetworkAgent.disconnect();
+
+        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        callback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        callback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
     }
 
     private void tryNetworkFactoryRequests(int capability) throws Exception {
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index 3172c6e..bc89c0f 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -56,6 +56,8 @@
 import android.telephony.CarrierConfigManager;
 
 import com.android.internal.util.test.BroadcastInterceptingContext;
+import com.android.server.connectivity.tethering.OffloadHardwareInterface;
+import com.android.server.connectivity.tethering.TetheringDependencies;
 
 import org.junit.After;
 import org.junit.Before;
@@ -78,7 +80,9 @@
     @Mock private INetworkStatsService mStatsService;
     @Mock private INetworkPolicyManager mPolicyManager;
     @Mock private MockableSystemProperties mSystemProperties;
+    @Mock private OffloadHardwareInterface mOffloadHardwareInterface;
     @Mock private Resources mResources;
+    @Mock private TetheringDependencies mTetheringDependencies;
     @Mock private UsbManager mUsbManager;
     @Mock private WifiManager mWifiManager;
     @Mock private CarrierConfigManager mCarrierConfigManager;
@@ -138,8 +142,11 @@
         };
         mServiceContext.registerReceiver(mBroadcastReceiver,
                 new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED));
+        when(mTetheringDependencies.getOffloadHardwareInterface())
+                .thenReturn(mOffloadHardwareInterface);
         mTethering = new Tethering(mServiceContext, mNMService, mStatsService, mPolicyManager,
-                                   mLooper.getLooper(), mSystemProperties);
+                                   mLooper.getLooper(), mSystemProperties,
+                                   mTetheringDependencies);
     }
 
     @After
diff --git a/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java b/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
index a3f33dc..27e683c 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
@@ -38,6 +38,7 @@
 import android.net.ConnectivityManager;
 import android.net.INetworkStatsService;
 import android.net.InterfaceConfiguration;
+import android.net.util.SharedLog;
 import android.os.INetworkManagementService;
 import android.os.RemoteException;
 import android.os.test.TestLooper;
@@ -63,12 +64,14 @@
     @Mock private IControlsTethering mTetherHelper;
     @Mock private InterfaceConfiguration mInterfaceConfiguration;
     @Mock private IPv6TetheringInterfaceServices mIPv6TetheringInterfaceServices;
+    @Mock private SharedLog mSharedLog;
 
     private final TestLooper mLooper = new TestLooper();
     private TetherInterfaceStateMachine mTestedSm;
 
     private void initStateMachine(int interfaceType) throws Exception {
-        mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(), interfaceType,
+        mTestedSm = new TetherInterfaceStateMachine(
+                IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog,
                 mNMService, mStatsService, mTetherHelper, mIPv6TetheringInterfaceServices);
         mTestedSm.start();
         // Starting the state machine always puts us in a consistent state and notifies
@@ -90,12 +93,13 @@
 
     @Before public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        when(mSharedLog.forSubComponent(anyString())).thenReturn(mSharedLog);
     }
 
     @Test
     public void startsOutAvailable() {
         mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(),
-                TETHERING_BLUETOOTH, mNMService, mStatsService, mTetherHelper,
+                TETHERING_BLUETOOTH, mSharedLog, mNMService, mStatsService, mTetherHelper,
                 mIPv6TetheringInterfaceServices);
         mTestedSm.start();
         mLooper.dispatchAll();
diff --git a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java b/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
index c72efb0..9bb392a 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
@@ -25,11 +25,13 @@
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.os.Handler;
@@ -40,6 +42,7 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
+import android.net.util.SharedLog;
 
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -69,6 +72,7 @@
 
     @Mock private Context mContext;
     @Mock private IConnectivityManager mCS;
+    @Mock private SharedLog mLog;
 
     private TestStateMachine mSM;
     private TestConnectivityManager mCM;
@@ -78,10 +82,12 @@
         MockitoAnnotations.initMocks(this);
         reset(mContext);
         reset(mCS);
+        reset(mLog);
+        when(mLog.forSubComponent(anyString())).thenReturn(mLog);
 
         mCM = spy(new TestConnectivityManager(mContext, mCS));
         mSM = new TestStateMachine();
-        mUNM = new UpstreamNetworkMonitor(mSM, EVENT_UNM_UPDATE, (ConnectivityManager) mCM);
+        mUNM = new UpstreamNetworkMonitor(mSM, EVENT_UNM_UPDATE, (ConnectivityManager) mCM, mLog);
     }
 
     @After public void tearDown() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsAccessTest.java b/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java
similarity index 98%
rename from services/tests/servicestests/src/com/android/server/net/NetworkStatsAccessTest.java
rename to tests/net/java/com/android/server/net/NetworkStatsAccessTest.java
index bb8f9d1..e6b1c6d 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsAccessTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java
@@ -25,6 +25,7 @@
 import android.app.admin.DevicePolicyManagerInternal;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.support.test.filters.SmallTest;
 import android.telephony.TelephonyManager;
 
 import com.android.server.LocalServices;
@@ -34,6 +35,7 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+@SmallTest
 public class NetworkStatsAccessTest extends TestCase {
     private static final String TEST_PKG = "com.example.test";
     private static final int TEST_UID = 12345;
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
similarity index 98%
rename from services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java
rename to tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
index 9f53c87..2a32b73 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
@@ -31,11 +31,11 @@
 import android.os.Process;
 import android.os.UserHandle;
 import android.telephony.TelephonyManager;
+import android.support.test.filters.SmallTest;
 import android.test.AndroidTestCase;
 import android.test.MoreAsserts;
-import android.test.suitebuilder.annotation.MediumTest;
 
-import com.android.frameworks.servicestests.R;
+import com.android.frameworks.tests.net.R;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -51,7 +51,7 @@
 /**
  * Tests for {@link NetworkStatsCollection}.
  */
-@MediumTest
+@SmallTest
 public class NetworkStatsCollectionTest extends AndroidTestCase {
 
     private static final String TEST_FILE = "test.bin";
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
similarity index 99%
rename from services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java
rename to tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
index 5eee7b9..fe7840d 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
@@ -38,16 +38,16 @@
 import android.net.NetworkIdentity;
 import android.net.NetworkStats;
 import android.net.NetworkTemplate;
+import android.os.ConditionVariable;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
-import android.os.Process;
-
-import android.os.ConditionVariable;
 import android.os.Looper;
-import android.os.Messenger;
 import android.os.Message;
+import android.os.Messenger;
+import android.os.Process;
 import android.os.UserHandle;
+import android.support.test.filters.SmallTest;
 import android.telephony.TelephonyManager;
 import android.util.ArrayMap;
 
@@ -69,6 +69,7 @@
 /**
  * Tests for {@link NetworkStatsObservers}.
  */
+@SmallTest
 public class NetworkStatsObserversTest extends TestCase {
     private static final String TEST_IFACE = "test0";
     private static final String TEST_IFACE2 = "test1";
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
similarity index 99%
rename from services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java
rename to tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 728eb73..029693f 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -85,6 +85,7 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.telephony.TelephonyManager;
 import android.test.AndroidTestCase;
@@ -119,6 +120,7 @@
  * still uses the Easymock structure, which could be simplified.
  */
 @RunWith(AndroidJUnit4.class)
+@SmallTest
 public class NetworkStatsServiceTest {
     private static final String TAG = "NetworkStatsServiceTest";
 
diff --git a/services/tests/servicestests/res/raw/netstats_uid_v4 b/tests/net/res/raw/netstats_uid_v4
similarity index 100%
rename from services/tests/servicestests/res/raw/netstats_uid_v4
rename to tests/net/res/raw/netstats_uid_v4
Binary files differ
diff --git a/services/tests/servicestests/res/raw/netstats_v1 b/tests/net/res/raw/netstats_v1
similarity index 100%
rename from services/tests/servicestests/res/raw/netstats_v1
rename to tests/net/res/raw/netstats_v1
Binary files differ
diff --git a/tests/radio/Android.mk b/tests/radio/Android.mk
index 46bf9cc..dc55d0b 100644
--- a/tests/radio/Android.mk
+++ b/tests/radio/Android.mk
@@ -22,7 +22,7 @@
 # TODO(b/13282254): uncomment when b/13282254 is fixed
 # LOCAL_SDK_VERSION := current
 
-LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util android-support-test
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util android-support-test testng
 
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/radio/src/android/hardware/radio/tests/RadioTest.java b/tests/radio/src/android/hardware/radio/tests/RadioTest.java
index a068ba1..47e104c 100644
--- a/tests/radio/src/android/hardware/radio/tests/RadioTest.java
+++ b/tests/radio/src/android/hardware/radio/tests/RadioTest.java
@@ -21,6 +21,7 @@
 import android.hardware.radio.RadioTuner;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
 
 import java.lang.reflect.Constructor;
 import java.util.ArrayList;
@@ -46,12 +47,14 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.testng.Assert.assertThrows;
 
 /**
  * A test for broadcast radio API.
  */
 @RunWith(AndroidJUnit4.class)
 public class RadioTest {
+    private static final String TAG = "RadioTest";
 
     public final Context mContext = InstrumentationRegistry.getContext();
 
@@ -61,6 +64,7 @@
 
     private RadioManager mRadioManager;
     private RadioTuner mRadioTuner;
+    private RadioManager.ModuleProperties mModule;
     private final List<RadioManager.ModuleProperties> mModules = new ArrayList<>();
     @Mock private RadioTuner.Callback mCallback;
 
@@ -111,8 +115,8 @@
         assertNull(mRadioTuner);
 
         // find FM band and build its config
-        RadioManager.ModuleProperties module = mModules.get(0);
-        for (RadioManager.BandDescriptor band : module.getBands()) {
+        mModule = mModules.get(0);
+        for (RadioManager.BandDescriptor band : mModule.getBands()) {
             if (band.getType() == RadioManager.BAND_AM) {
                 mAmBandDescriptor = (RadioManager.AmBandDescriptor)band;
             }
@@ -125,7 +129,7 @@
         mAmBandConfig = new RadioManager.AmBandConfig.Builder(mAmBandDescriptor).build();
         mFmBandConfig = new RadioManager.FmBandConfig.Builder(mFmBandDescriptor).build();
 
-        mRadioTuner = mRadioManager.openTuner(module.getId(),
+        mRadioTuner = mRadioManager.openTuner(mModule.getId(),
                 mFmBandConfig, withAudio, mCallback, null);
         assertNotNull(mRadioTuner);
         verify(mCallback, timeout(kConfigCallbackTimeoutMs)).onConfigurationChanged(any());
@@ -133,9 +137,8 @@
     }
 
     private void checkAntenna() {
-        // TODO(b/36863239): enable check when isAntennaConnected is implemented
-        //boolean isConnected = mRadioTuner.isAntennaConnected();
-        //assertTrue(isConnected);
+        boolean isConnected = mRadioTuner.isAntennaConnected();
+        assertTrue(isConnected);
     }
 
     @Test
@@ -318,4 +321,55 @@
         verify(mCallback, after(kCancelTimeoutMs).atMost(1)).onError(RadioTuner.ERROR_CANCELLED);
         verify(mCallback, atMost(1)).onProgramInfoChanged(any());
     }
+
+    @Test
+    public void testStartBackgroundScan() {
+        openTuner();
+        checkAntenna();
+
+        boolean ret = mRadioTuner.startBackgroundScan();
+        boolean isSupported = mModule.isBackgroundScanningSupported();
+        assertEquals(isSupported, ret);
+    }
+
+    @Test
+    public void testGetProgramList() {
+        openTuner();
+        checkAntenna();
+
+        try {
+            List<RadioManager.ProgramInfo> list = mRadioTuner.getProgramList(null);
+            assertNotNull(list);
+        } catch (IllegalStateException e) {
+            // the list may or may not be ready at this point
+            Log.i(TAG, "Background list is not ready");
+        }
+    }
+
+    @Test
+    public void testForcedAnalog() {
+        openTuner();
+
+        boolean isSupported = true;
+        boolean isForced;
+        try {
+            isForced = mRadioTuner.isAnalogForced();
+            assertFalse(isForced);
+        } catch (IllegalStateException ex) {
+            Log.i(TAG, "Forced analog switch is not supported by this tuner");
+            isSupported = false;
+        }
+
+        if (isSupported) {
+            mRadioTuner.setAnalogForced(true);
+            isForced = mRadioTuner.isAnalogForced();
+            assertTrue(isForced);
+
+            mRadioTuner.setAnalogForced(false);
+            isForced = mRadioTuner.isAnalogForced();
+            assertFalse(isForced);
+        } else {
+            assertThrows(IllegalStateException.class, () -> mRadioTuner.setAnalogForced(true));
+        }
+    }
 }
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 6dfabf1..10244da 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -34,42 +34,43 @@
 
 namespace aapt {
 
-constexpr const char* sXliffNamespaceUri =
-    "urn:oasis:names:tc:xliff:document:1.2";
+constexpr const char* sXliffNamespaceUri = "urn:oasis:names:tc:xliff:document:1.2";
 
-/**
- * Returns true if the element is <skip> or <eat-comment> and can be safely
- * ignored.
- */
-static bool ShouldIgnoreElement(const StringPiece& ns,
-                                const StringPiece& name) {
+// Returns true if the element is <skip> or <eat-comment> and can be safely ignored.
+static bool ShouldIgnoreElement(const StringPiece& ns, const StringPiece& name) {
   return ns.empty() && (name == "skip" || name == "eat-comment");
 }
 
-static uint32_t ParseFormatType(const StringPiece& piece) {
-  if (piece == "reference")
+static uint32_t ParseFormatTypeNoEnumsOrFlags(const StringPiece& piece) {
+  if (piece == "reference") {
     return android::ResTable_map::TYPE_REFERENCE;
-  else if (piece == "string")
+  } else if (piece == "string") {
     return android::ResTable_map::TYPE_STRING;
-  else if (piece == "integer")
+  } else if (piece == "integer") {
     return android::ResTable_map::TYPE_INTEGER;
-  else if (piece == "boolean")
+  } else if (piece == "boolean") {
     return android::ResTable_map::TYPE_BOOLEAN;
-  else if (piece == "color")
+  } else if (piece == "color") {
     return android::ResTable_map::TYPE_COLOR;
-  else if (piece == "float")
+  } else if (piece == "float") {
     return android::ResTable_map::TYPE_FLOAT;
-  else if (piece == "dimension")
+  } else if (piece == "dimension") {
     return android::ResTable_map::TYPE_DIMENSION;
-  else if (piece == "fraction")
+  } else if (piece == "fraction") {
     return android::ResTable_map::TYPE_FRACTION;
-  else if (piece == "enum")
-    return android::ResTable_map::TYPE_ENUM;
-  else if (piece == "flags")
-    return android::ResTable_map::TYPE_FLAGS;
+  }
   return 0;
 }
 
+static uint32_t ParseFormatType(const StringPiece& piece) {
+  if (piece == "enum") {
+    return android::ResTable_map::TYPE_ENUM;
+  } else if (piece == "flags") {
+    return android::ResTable_map::TYPE_FLAGS;
+  }
+  return ParseFormatTypeNoEnumsOrFlags(piece);
+}
+
 static uint32_t ParseFormatAttribute(const StringPiece& str) {
   uint32_t mask = 0;
   for (StringPiece part : util::Tokenize(str, '|')) {
@@ -83,9 +84,7 @@
   return mask;
 }
 
-/**
- * A parsed resource ready to be added to the ResourceTable.
- */
+// A parsed resource ready to be added to the ResourceTable.
 struct ParsedResource {
   ResourceName name;
   ConfigDescription config;
@@ -416,8 +415,7 @@
     can_be_bag = false;
 
     // Items have their type encoded in the type attribute.
-    if (Maybe<StringPiece> maybe_type =
-            xml::FindNonEmptyAttribute(parser, "type")) {
+    if (Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type")) {
       resource_type = maybe_type.value().to_string();
     } else {
       diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
@@ -425,13 +423,11 @@
       return false;
     }
 
-    if (Maybe<StringPiece> maybe_format =
-            xml::FindNonEmptyAttribute(parser, "format")) {
+    if (Maybe<StringPiece> maybe_format = xml::FindNonEmptyAttribute(parser, "format")) {
       // An explicit format for this resource was specified. The resource will
-      // retain
-      // its type in its name, but the accepted value for this type is
+      // retain its type in its name, but the accepted value for this type is
       // overridden.
-      resource_format = ParseFormatType(maybe_format.value());
+      resource_format = ParseFormatTypeNoEnumsOrFlags(maybe_format.value());
       if (!resource_format) {
         diag_->Error(DiagMessage(out_resource->source)
                      << "'" << maybe_format.value()
@@ -1157,21 +1153,25 @@
   return true;
 }
 
-bool ResourceParser::ParseArray(xml::XmlPullParser* parser,
-                                ParsedResource* out_resource) {
-  return ParseArrayImpl(parser, out_resource, android::ResTable_map::TYPE_ANY);
+bool ResourceParser::ParseArray(xml::XmlPullParser* parser, ParsedResource* out_resource) {
+  uint32_t resource_format = android::ResTable_map::TYPE_ANY;
+  if (Maybe<StringPiece> format_attr = xml::FindNonEmptyAttribute(parser, "format")) {
+    resource_format = ParseFormatTypeNoEnumsOrFlags(format_attr.value());
+    if (resource_format == 0u) {
+      diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
+                   << "'" << format_attr.value() << "' is an invalid format");
+      return false;
+    }
+  }
+  return ParseArrayImpl(parser, out_resource, resource_format);
 }
 
-bool ResourceParser::ParseIntegerArray(xml::XmlPullParser* parser,
-                                       ParsedResource* out_resource) {
-  return ParseArrayImpl(parser, out_resource,
-                        android::ResTable_map::TYPE_INTEGER);
+bool ResourceParser::ParseIntegerArray(xml::XmlPullParser* parser, ParsedResource* out_resource) {
+  return ParseArrayImpl(parser, out_resource, android::ResTable_map::TYPE_INTEGER);
 }
 
-bool ResourceParser::ParseStringArray(xml::XmlPullParser* parser,
-                                      ParsedResource* out_resource) {
-  return ParseArrayImpl(parser, out_resource,
-                        android::ResTable_map::TYPE_STRING);
+bool ResourceParser::ParseStringArray(xml::XmlPullParser* parser, ParsedResource* out_resource) {
+  return ParseArrayImpl(parser, out_resource, android::ResTable_map::TYPE_STRING);
 }
 
 bool ResourceParser::ParseArrayImpl(xml::XmlPullParser* parser,
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 8062c2e6..faa6607 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -571,14 +571,39 @@
 }
 
 TEST_F(ResourceParserTest, ParseStringArray) {
-  std::string input =
-      "<string-array name=\"foo\">\n"
-      "  <item>\"Werk\"</item>\n"
-      "</string-array>\n";
+  std::string input = R"EOF(
+      <string-array name="foo">
+        <item>"Werk"</item>"
+      </string-array>)EOF";
   ASSERT_TRUE(TestParse(input));
   EXPECT_NE(nullptr, test::GetValue<Array>(&table_, "array/foo"));
 }
 
+TEST_F(ResourceParserTest, ParseArrayWithFormat) {
+  std::string input = R"EOF(
+      <array name="foo" format="string">
+        <item>100</item>
+      </array>)EOF";
+  ASSERT_TRUE(TestParse(input));
+
+  Array* array = test::GetValue<Array>(&table_, "array/foo");
+  ASSERT_NE(nullptr, array);
+
+  ASSERT_EQ(1u, array->items.size());
+
+  String* str = ValueCast<String>(array->items[0].get());
+  ASSERT_NE(nullptr, str);
+  EXPECT_EQ(std::string("100"), *str->value);
+}
+
+TEST_F(ResourceParserTest, ParseArrayWithBadFormat) {
+  std::string input = R"EOF(
+      <array name="foo" format="integer">
+        <item>Hi</item>
+      </array>)EOF";
+  ASSERT_FALSE(TestParse(input));
+}
+
 TEST_F(ResourceParserTest, ParsePlural) {
   std::string input =
       "<plurals name=\"foo\">\n"
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index c192d69..5adf04a 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -372,6 +372,8 @@
     if (file_type == file::FileType::kDirectory) {
       context->GetDiagnostics()->Error(DiagMessage(input_path)
                                        << "resource file cannot be a directory");
+    } else if (file_type == file::FileType::kNonexistant) {
+      context->GetDiagnostics()->Error(DiagMessage(input_path) << "file not found");
     } else {
       context->GetDiagnostics()->Error(DiagMessage(input_path)
                                        << "not a valid resource file");
@@ -488,7 +490,7 @@
     // Ensure that we only keep the chunks we care about if we end up
     // using the original PNG instead of the crunched one.
     PngChunkFilter png_chunk_filter(content);
-    std::unique_ptr<Image> image = ReadPng(context, &png_chunk_filter);
+    std::unique_ptr<Image> image = ReadPng(context, path_data.source, &png_chunk_filter);
     if (!image) {
       return false;
     }
diff --git a/tools/aapt2/compile/Png.h b/tools/aapt2/compile/Png.h
index e4255e7..7ca1f0e 100644
--- a/tools/aapt2/compile/Png.h
+++ b/tools/aapt2/compile/Png.h
@@ -69,7 +69,12 @@
   bool Rewind() override;
   size_t ByteCount() const override { return window_start_; }
 
-  bool HadError() const override { return error_; }
+  bool HadError() const override {
+    return !error_msg_.empty();
+  }
+  std::string GetError() const override {
+    return error_msg_;
+  }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(PngChunkFilter);
@@ -79,13 +84,13 @@
   android::StringPiece data_;
   size_t window_start_ = 0;
   size_t window_end_ = 0;
-  bool error_ = false;
+  std::string error_msg_;
 };
 
 /**
  * Reads a PNG from the InputStream into memory as an RGBA Image.
  */
-std::unique_ptr<Image> ReadPng(IAaptContext* context, io::InputStream* in);
+std::unique_ptr<Image> ReadPng(IAaptContext* context, const Source& source, io::InputStream* in);
 
 /**
  * Writes the RGBA Image, with optional 9-patch meta-data, into the OutputStream
diff --git a/tools/aapt2/compile/PngChunkFilter.cpp b/tools/aapt2/compile/PngChunkFilter.cpp
index f9043b5..7073c13 100644
--- a/tools/aapt2/compile/PngChunkFilter.cpp
+++ b/tools/aapt2/compile/PngChunkFilter.cpp
@@ -16,11 +16,13 @@
 
 #include "compile/Png.h"
 
+#include "android-base/stringprintf.h"
 #include "androidfw/StringPiece.h"
 
 #include "io/Io.h"
 
 using android::StringPiece;
+using android::base::StringPrintf;
 
 namespace aapt {
 
@@ -73,7 +75,7 @@
     window_start_ = 0;
     window_end_ = kPngSignatureSize;
   } else {
-    error_ = true;
+    error_msg_ = "PNG does not start with PNG signature";
   }
 }
 
@@ -90,7 +92,7 @@
 }
 
 bool PngChunkFilter::Next(const void** buffer, size_t* len) {
-  if (error_) {
+  if (HadError()) {
     return false;
   }
 
@@ -106,16 +108,21 @@
     const size_t kMinChunkHeaderSize = 3 * sizeof(uint32_t);
 
     // Is there enough room for a chunk header?
-    if (data_.size() - window_start_ < kMinChunkHeaderSize) {
-      error_ = true;
+    if (data_.size() - window_end_ < kMinChunkHeaderSize) {
+      error_msg_ = StringPrintf("Not enough space for a PNG chunk @ byte %zu/%zu", window_end_,
+                                data_.size());
       return false;
     }
 
     // Verify the chunk length.
     const uint32_t chunk_len = Peek32LE(data_.data() + window_end_);
-    if (((uint64_t)chunk_len) + ((uint64_t)window_end_) + sizeof(uint32_t) > data_.size()) {
+    if ((size_t)chunk_len > data_.size() - window_end_ - kMinChunkHeaderSize) {
       // Overflow.
-      error_ = true;
+      const uint32_t chunk_type = Peek32LE(data_.data() + window_end_ + sizeof(uint32_t));
+      error_msg_ = StringPrintf(
+          "PNG chunk type %08x is too large: chunk length is %zu but chunk "
+          "starts at byte %zu/%zu",
+          chunk_type, (size_t)chunk_len, window_end_ + kMinChunkHeaderSize, data_.size());
       return false;
     }
 
@@ -124,6 +131,16 @@
     if (IsPngChunkWhitelisted(chunk_type)) {
       // Advance the window to include this chunk.
       window_end_ += kMinChunkHeaderSize + chunk_len;
+
+      // Special case the IEND chunk, which MUST appear last and libpng stops parsing once it hits
+      // such a chunk (let's do the same).
+      if (chunk_type == kPngChunkIEND) {
+        // Truncate the data to the end of this chunk. There may be garbage trailing after
+        // (b/38169876)
+        data_ = data_.substr(0, window_end_);
+        break;
+      }
+
     } else {
       // We want to strip this chunk. If we accumulated a window,
       // we must return the window now.
@@ -145,14 +162,14 @@
 }
 
 void PngChunkFilter::BackUp(size_t count) {
-  if (error_) {
+  if (HadError()) {
     return;
   }
   window_start_ -= count;
 }
 
 bool PngChunkFilter::Rewind() {
-  if (error_) {
+  if (HadError()) {
     return false;
   }
   window_start_ = 0;
diff --git a/tools/aapt2/compile/PngCrunch.cpp b/tools/aapt2/compile/PngCrunch.cpp
index ae98afc..42443d8 100644
--- a/tools/aapt2/compile/PngCrunch.cpp
+++ b/tools/aapt2/compile/PngCrunch.cpp
@@ -73,6 +73,11 @@
 static void LogError(png_structp png_ptr, png_const_charp error_msg) {
   IDiagnostics* diag = (IDiagnostics*)png_get_error_ptr(png_ptr);
   diag->Error(DiagMessage() << error_msg);
+
+  // Causes libpng to longjmp to the spot where setjmp was set. This is how libpng does
+  // error handling. If this custom error handler method were to return, libpng would, by
+  // default, print the error message to stdout and call the same png_longjmp method.
+  png_longjmp(png_ptr, 1);
 }
 
 static void ReadDataFromStream(png_structp png_ptr, png_bytep buffer, png_size_t len) {
@@ -82,7 +87,12 @@
   size_t in_len;
   if (!in->Next(&in_buffer, &in_len)) {
     if (in->HadError()) {
-      std::string err = in->GetError();
+      std::stringstream error_msg_builder;
+      error_msg_builder << "failed reading from input";
+      if (!in->GetError().empty()) {
+        error_msg_builder << ": " << in->GetError();
+      }
+      std::string err = error_msg_builder.str();
       png_error(png_ptr, err.c_str());
     }
     return;
@@ -103,6 +113,11 @@
   while (len > 0) {
     if (!out->Next(&out_buffer, &out_len)) {
       if (out->HadError()) {
+        std::stringstream err_msg_builder;
+        err_msg_builder << "failed writing to output";
+        if (!out->GetError().empty()) {
+          err_msg_builder << ": " << out->GetError();
+        }
         std::string err = out->GetError();
         png_error(png_ptr, err.c_str());
       }
@@ -126,7 +141,7 @@
   }
 }
 
-std::unique_ptr<Image> ReadPng(IAaptContext* context, io::InputStream* in) {
+std::unique_ptr<Image> ReadPng(IAaptContext* context, const Source& source, io::InputStream* in) {
   // Read the first 8 bytes of the file looking for the PNG signature.
   // Bail early if it does not match.
   const png_byte* signature;
@@ -163,6 +178,9 @@
     return {};
   }
 
+  // Create a diagnostics that has the source information encoded.
+  SourcePathDiagnostics source_diag(source, context->GetDiagnostics());
+
   // Automatically release PNG resources at end of scope.
   PngReadStructDeleter png_read_deleter(read_ptr, info_ptr);
 
@@ -174,7 +192,7 @@
   }
 
   // Handle warnings ourselves via IDiagnostics.
-  png_set_error_fn(read_ptr, (png_voidp)context->GetDiagnostics(), LogError, LogWarning);
+  png_set_error_fn(read_ptr, (png_voidp)&source_diag, LogError, LogWarning);
 
   // Set up the read functions which read from our custom data sources.
   png_set_read_fn(read_ptr, (png_voidp)in, ReadDataFromStream);
@@ -231,8 +249,8 @@
   // something
   // that can always be represented by 9-patch.
   if (width > std::numeric_limits<int32_t>::max() || height > std::numeric_limits<int32_t>::max()) {
-    context->GetDiagnostics()->Error(
-        DiagMessage() << "PNG image dimensions are too large: " << width << "x" << height);
+    source_diag.Error(DiagMessage()
+                      << "PNG image dimensions are too large: " << width << "x" << height);
     return {};
   }
 
diff --git a/tools/aapt2/filter/ConfigFilter.cpp b/tools/aapt2/filter/ConfigFilter.cpp
index 66aff82..5fbe77e 100644
--- a/tools/aapt2/filter/ConfigFilter.cpp
+++ b/tools/aapt2/filter/ConfigFilter.cpp
@@ -38,6 +38,43 @@
   config_mask_ |= diff_mask;
 }
 
+// Returns true if the locale script of the config should be considered matching
+// the locale script of entry.
+//
+// If both the scripts are empty, the scripts are considered matching for
+// backward compatibility reasons.
+//
+// If only one script is empty, we try to compute it based on the provided
+// language and country. If we could not compute it, we assume it's either a
+// new language we don't know about, or a private use language. We return true
+// since we don't know any better and they might as well be a match.
+//
+// Finally, when we have two scripts (one of which could be computed), we return
+// true if and only if they are an exact match.
+static bool ScriptsMatch(const ConfigDescription& config, const ConfigDescription& entry) {
+  const char* config_script = config.localeScript;
+  const char* entry_script = entry.localeScript;
+  if (config_script[0] == '\0' && entry_script[0] == '\0') {
+    return true;  // both scripts are empty. We match for backward compatibility reasons.
+  }
+
+  char script_buffer[sizeof(config.localeScript)];
+  if (config_script[0] == '\0') {
+    android::localeDataComputeScript(script_buffer, config.language, config.country);
+    if (script_buffer[0] == '\0') {  // We can't compute the script, so we match.
+      return true;
+    }
+    config_script = script_buffer;
+  } else if (entry_script[0] == '\0') {
+    android::localeDataComputeScript(script_buffer, entry.language, entry.country);
+    if (script_buffer[0] == '\0') {  // We can't compute the script, so we match.
+      return true;
+    }
+    entry_script = script_buffer;
+  }
+  return memcmp(config_script, entry_script, sizeof(config.localeScript)) == 0;
+}
+
 bool AxisConfigFilter::Match(const ConfigDescription& config) const {
   const uint32_t mask = ConfigDescription::DefaultConfig().diff(config);
   if ((config_mask_ & mask) == 0) {
@@ -57,12 +94,16 @@
       // If the locales differ, but the languages are the same and
       // the locale we are matching only has a language specified,
       // we match.
-      if (config.language[0] &&
-          memcmp(config.language, target.language, sizeof(config.language)) ==
-              0) {
-        if (config.country[0] == 0) {
-          matched_axis |= android::ResTable_config::CONFIG_LOCALE;
-        }
+      //
+      // Exception: we won't match if a script is specified for at least
+      // one of the locales and it's different from the other locale's
+      // script. (We will compute the other script if at least one of the
+      // scripts were explicitly set. In cases we can't compute an script,
+      // we match.)
+      if (config.language[0] != '\0' && config.country[0] == '\0' &&
+          config.localeVariant[0] == '\0' && config.language[0] == entry.first.language[0] &&
+          config.language[1] == entry.first.language[1] && ScriptsMatch(config, entry.first)) {
+        matched_axis |= android::ResTable_config::CONFIG_LOCALE;
       }
     } else if ((diff & diff_mask) ==
                android::ResTable_config::CONFIG_SMALLEST_SCREEN_SIZE) {
diff --git a/tools/aapt2/filter/ConfigFilter_test.cpp b/tools/aapt2/filter/ConfigFilter_test.cpp
index 586dd5f..4a31080 100644
--- a/tools/aapt2/filter/ConfigFilter_test.cpp
+++ b/tools/aapt2/filter/ConfigFilter_test.cpp
@@ -109,4 +109,20 @@
   EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("kok-rIN")));
 }
 
+TEST(ConfigFilterTest, MatchesScripts) {
+  AxisConfigFilter filter;
+
+  // "sr" gets automatically computed the script "Cyrl"
+  filter.AddConfig(test::ParseConfigOrDie("sr"));
+
+  // "sr" -> "b+sr+Cyrl"
+  EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("b+sr+Cyrl")));
+
+  // The incoming "sr" is also auto-computed to "b+sr+Cyrl".
+  EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("sr")));
+
+  // "sr" -> "b+sr+Cyrl", which doesn't match "Latn".
+  EXPECT_FALSE(filter.Match(test::ParseConfigOrDie("b+sr+Latn")));
+}
+
 }  // namespace aapt
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index d942d05..088cbc6 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -131,7 +131,7 @@
 
     boolean stopSoftAp();
 
-    int startLocalOnlyHotspot(in Messenger messenger, in IBinder binder);
+    int startLocalOnlyHotspot(in Messenger messenger, in IBinder binder, in String packageName);
 
     void stopLocalOnlyHotspot();
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index e59b74f..25d61af 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -452,6 +452,15 @@
     public static final int SAP_START_FAILURE_NO_CHANNEL = 1;
 
     /**
+     * Interface IP mode unspecified.
+     *
+     * @see updateInterfaceIpState(String, int)
+     *
+     * @hide
+     */
+    public static final int IFACE_IP_MODE_UNSPECIFIED = -1;
+
+    /**
      * Interface IP mode for configuration error.
      *
      * @see updateInterfaceIpState(String, int)
@@ -1890,7 +1899,9 @@
             LocalOnlyHotspotCallbackProxy proxy =
                     new LocalOnlyHotspotCallbackProxy(this, looper, callback);
             try {
-                int returnCode = mService.startLocalOnlyHotspot(proxy.getMessenger(), new Binder());
+                String packageName = mContext.getOpPackageName();
+                int returnCode = mService.startLocalOnlyHotspot(
+                        proxy.getMessenger(), new Binder(), packageName);
                 if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) {
                     // Send message to the proxy to make sure we call back on the correct thread
                     proxy.notifyFailed(returnCode);
diff --git a/wifi/java/android/net/wifi/aware/PublishConfig.java b/wifi/java/android/net/wifi/aware/PublishConfig.java
index 0f1e992..d018620 100644
--- a/wifi/java/android/net/wifi/aware/PublishConfig.java
+++ b/wifi/java/android/net/wifi/aware/PublishConfig.java
@@ -93,12 +93,17 @@
 
     @Override
     public String toString() {
-        return "PublishConfig [mServiceName='" + mServiceName + ", mServiceSpecificInfo='" + (
-                (mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo))
-                + ", mMatchFilter=" + (new TlvBufferUtils.TlvIterable(0, 1,
-                mMatchFilter)).toString() + ", mPublishType=" + mPublishType
-                + ", mTtlSec=" + mTtlSec + ", mEnableTerminateNotification="
-                + mEnableTerminateNotification + "]";
+        return "PublishConfig [mServiceName='" + (mServiceName == null ? "<null>" : String.valueOf(
+                HexEncoding.encode(mServiceName))) + ", mServiceName.length=" + (
+                mServiceName == null ? 0 : mServiceName.length) + ", mServiceSpecificInfo='" + (
+                (mServiceSpecificInfo == null) ? "<null>" : String.valueOf(
+                        HexEncoding.encode(mServiceSpecificInfo)))
+                + ", mServiceSpecificInfo.length=" + (mServiceSpecificInfo == null ? 0
+                : mServiceSpecificInfo.length) + ", mMatchFilter="
+                + (new TlvBufferUtils.TlvIterable(0, 1, mMatchFilter)).toString()
+                + ", mMatchFilter.length=" + (mMatchFilter == null ? 0 : mMatchFilter.length)
+                + ", mPublishType=" + mPublishType + ", mTtlSec=" + mTtlSec
+                + ", mEnableTerminateNotification=" + mEnableTerminateNotification + "]";
     }
 
     @Override
diff --git a/wifi/java/android/net/wifi/aware/SubscribeConfig.java b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
index 31e7e8e..4bf2fb6 100644
--- a/wifi/java/android/net/wifi/aware/SubscribeConfig.java
+++ b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
@@ -92,13 +92,17 @@
 
     @Override
     public String toString() {
-        return "SubscribeConfig [mServiceName='" + mServiceName + ", mServiceSpecificInfo='" + (
-                (mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo))
-                + ", mMatchFilter=" + (new TlvBufferUtils.TlvIterable(0, 1,
-                mMatchFilter)).toString() + ", mSubscribeType=" + mSubscribeType
-                + ", mTtlSec=" + mTtlSec
-                + ", mEnableTerminateNotification=" + mEnableTerminateNotification
-                + "]";
+        return "SubscribeConfig [mServiceName='" + (mServiceName == null ? "<null>"
+                : String.valueOf(HexEncoding.encode(mServiceName))) + ", mServiceName.length=" + (
+                mServiceName == null ? 0 : mServiceName.length) + ", mServiceSpecificInfo='" + (
+                (mServiceSpecificInfo == null) ? "<null>" : String.valueOf(
+                        HexEncoding.encode(mServiceSpecificInfo)))
+                + ", mServiceSpecificInfo.length=" + (mServiceSpecificInfo == null ? 0
+                : mServiceSpecificInfo.length) + ", mMatchFilter="
+                + (new TlvBufferUtils.TlvIterable(0, 1, mMatchFilter)).toString()
+                + ", mMatchFilter.length=" + (mMatchFilter == null ? 0 : mMatchFilter.length)
+                + ", mSubscribeType=" + mSubscribeType + ", mTtlSec=" + mTtlSec
+                + ", mEnableTerminateNotification=" + mEnableTerminateNotification + "]";
     }
 
     @Override
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
index 92c7e36..ebf5c2a 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
@@ -139,7 +139,7 @@
 
     public String getDeviceInfoHex() {
         return String.format(
-                Locale.US, "%04x%04x%04x%04x", 6, mDeviceInfo, mCtrlPort, mMaxThroughput);
+                Locale.US, "%04x%04x%04x", mDeviceInfo, mCtrlPort, mMaxThroughput);
     }
 
     public String toString() {
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.java
index a0b5a6e..1020fd2 100644
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.java
+++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.java
@@ -186,31 +186,23 @@
     /**
      * Create the list of  WifiP2pServiceResponse instance from supplicant event.
      *
-     * <pre>The format is as follows.
-     * P2P-SERV-DISC-RESP &lt;address&gt; &lt;update indicator&gt; &lt;response data&gt;
-     * e.g) P2P-SERV-DISC-RESP 02:03:7f:11:62:da 1 0300000101
-     *
-     * @param supplicantEvent wpa_supplicant event string.
+     * @param srcAddr source address of the service response
+     * @param tlvsBin byte array containing the binary tlvs data
      * @return if parse failed, return null
      * @hide
      */
-    public static List<WifiP2pServiceResponse> newInstance(String supplicantEvent) {
+    public static List<WifiP2pServiceResponse> newInstance(String srcAddr, byte[] tlvsBin) {
+        //updateIndicator not used, and not passed up from supplicant
 
         List<WifiP2pServiceResponse> respList = new ArrayList<WifiP2pServiceResponse>();
-        String[] args = supplicantEvent.split(" ");
-        if (args.length != 4) {
-            return null;
-        }
         WifiP2pDevice dev = new WifiP2pDevice();
-        String srcAddr = args[1];
         dev.deviceAddress = srcAddr;
-        //String updateIndicator = args[2];//not used.
-        byte[] bin = hexStr2Bin(args[3]);
-        if (bin == null) {
+        if (tlvsBin == null) {
             return null;
         }
 
-        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bin));
+
+        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(tlvsBin));
         try {
             while (dis.available() > 0) {
                 /*
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index adf897d..84ac118 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -58,6 +58,7 @@
 
     private static final int ERROR_NOT_SET = -1;
     private static final int ERROR_TEST_REASON = 5;
+    private static final String TEST_PACKAGE_NAME = "TestPackage";
 
     @Mock Context mContext;
     @Mock IWifiManager mWifiService;
@@ -76,6 +77,7 @@
         mLooper = new TestLooper();
         mHandler = spy(new Handler(mLooper.getLooper()));
         when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo);
+        when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
 
         mWifiServiceMessenger = new Messenger(mHandler);
         mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper());
@@ -126,8 +128,8 @@
     @Test
     public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception {
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
-                            .thenReturn(REQUEST_REGISTERED);
+        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+                anyString())).thenReturn(REQUEST_REGISTERED);
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
 
         callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig));
@@ -144,8 +146,8 @@
     public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources()
             throws Exception {
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
-                .thenReturn(REQUEST_REGISTERED);
+        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+                anyString())).thenReturn(REQUEST_REGISTERED);
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
 
         callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig));
@@ -304,7 +306,8 @@
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
 
-        verify(mWifiService).startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
+        verify(mWifiService)
+                .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
     }
 
     /**
@@ -315,7 +318,7 @@
     public void testStartLocalOnlyHotspotThrowsSecurityException() throws Exception {
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
         doThrow(new SecurityException()).when(mWifiService)
-                .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
+                .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
     }
 
@@ -327,7 +330,7 @@
     public void testStartLocalOnlyHotspotThrowsIllegalStateException() throws Exception {
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
         doThrow(new IllegalStateException()).when(mWifiService)
-                .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
+                .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
     }
 
@@ -337,8 +340,8 @@
     @Test
     public void testCorrectLooperIsUsedForHandler() throws Exception {
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
-                .thenReturn(ERROR_INCOMPATIBLE_MODE);
+        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+                anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
         mLooper.dispatchAll();
         assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
@@ -355,8 +358,8 @@
         TestLooper altLooper = new TestLooper();
         when(mContext.getMainLooper()).thenReturn(altLooper.getLooper());
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
-                .thenReturn(ERROR_INCOMPATIBLE_MODE);
+        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+                anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
         mWifiManager.startLocalOnlyHotspot(callback, null);
         altLooper.dispatchAll();
         assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
@@ -374,7 +377,7 @@
         TestLooper callbackLooper = new TestLooper();
         Handler callbackHandler = new Handler(callbackLooper.getLooper());
         when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
-                  any(IBinder.class))).thenReturn(REQUEST_REGISTERED);
+                  any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
         mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
         callbackLooper.dispatchAll();
         mLooper.dispatchAll();
@@ -401,7 +404,7 @@
         TestLooper callbackLooper = new TestLooper();
         Handler callbackHandler = new Handler(callbackLooper.getLooper());
         when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
-                  any(IBinder.class))).thenReturn(REQUEST_REGISTERED);
+                  any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
         mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
         callbackLooper.dispatchAll();
         mLooper.dispatchAll();
@@ -426,7 +429,7 @@
         TestLooper callbackLooper = new TestLooper();
         Handler callbackHandler = new Handler(callbackLooper.getLooper());
         when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
-                  any(IBinder.class))).thenReturn(REQUEST_REGISTERED);
+                  any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
         mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
         callbackLooper.dispatchAll();
         mLooper.dispatchAll();
@@ -449,7 +452,7 @@
         TestLooper callbackLooper = new TestLooper();
         Handler callbackHandler = new Handler(callbackLooper.getLooper());
         when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
-                  any(IBinder.class))).thenReturn(REQUEST_REGISTERED);
+                  any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
         mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
         callbackLooper.dispatchAll();
         mLooper.dispatchAll();
@@ -470,8 +473,8 @@
     @Test
     public void testLocalOnlyHotspotCallbackFullOnIncompatibleMode() throws Exception {
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
-                .thenReturn(ERROR_INCOMPATIBLE_MODE);
+        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+                anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
         mLooper.dispatchAll();
         assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
@@ -486,8 +489,8 @@
     @Test
     public void testLocalOnlyHotspotCallbackFullOnTetheringDisallowed() throws Exception {
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
-                .thenReturn(ERROR_TETHERING_DISALLOWED);
+        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+                anyString())).thenReturn(ERROR_TETHERING_DISALLOWED);
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
         mLooper.dispatchAll();
         assertEquals(ERROR_TETHERING_DISALLOWED, callback.mFailureReason);
@@ -504,7 +507,7 @@
     public void testLocalOnlyHotspotCallbackFullOnSecurityException() throws Exception {
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
         doThrow(new SecurityException()).when(mWifiService)
-                .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
+                .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
         try {
             mWifiManager.startLocalOnlyHotspot(callback, mHandler);
         } catch (SecurityException e) {
@@ -524,8 +527,8 @@
     @Test
     public void testLocalOnlyHotspotCallbackFullOnNoChannelError() throws Exception {
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
-                .thenReturn(REQUEST_REGISTERED);
+        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+                anyString())).thenReturn(REQUEST_REGISTERED);
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
         mLooper.dispatchAll();
         //assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason);
@@ -540,8 +543,8 @@
     @Test
     public void testCancelLocalOnlyHotspotRequestCallsStopOnWifiService() throws Exception {
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
-                .thenReturn(REQUEST_REGISTERED);
+        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+                anyString())).thenReturn(REQUEST_REGISTERED);
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
         mWifiManager.cancelLocalOnlyHotspotRequest();
         verify(mWifiService).stopLocalOnlyHotspot();
@@ -562,8 +565,8 @@
     @Test
     public void testCallbackAfterLocalOnlyHotspotWasCancelled() throws Exception {
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
-                .thenReturn(REQUEST_REGISTERED);
+        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+                anyString())).thenReturn(REQUEST_REGISTERED);
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
         mWifiManager.cancelLocalOnlyHotspotRequest();
         verify(mWifiService).stopLocalOnlyHotspot();
@@ -581,8 +584,8 @@
     @Test
     public void testCancelAfterLocalOnlyHotspotCallbackTriggered() throws Exception {
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
-        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
-                .thenReturn(ERROR_INCOMPATIBLE_MODE);
+        when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+                anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
         mLooper.dispatchAll();
         assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);