Merge "Conslidate @MainHandler and similar to @Main (and similar)."
diff --git a/api/current.txt b/api/current.txt
index 86aa80b..94a913d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3955,6 +3955,7 @@
 
   public class ActivityManager {
     method public int addAppTask(@NonNull android.app.Activity, @NonNull android.content.Intent, @Nullable android.app.ActivityManager.TaskDescription, @NonNull android.graphics.Bitmap);
+    method public void appNotResponding(@NonNull String);
     method public boolean clearApplicationUserData();
     method public void clearWatchHeapLimit();
     method @RequiresPermission(android.Manifest.permission.DUMP) public void dumpPackageState(java.io.FileDescriptor, String);
diff --git a/api/system-current.txt b/api/system-current.txt
index 05e2ca5..c0f8ceb 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -8981,6 +8981,34 @@
     field public static final String CELL_BROADCAST_SERVICE_INTERFACE = "android.telephony.CellBroadcastService";
   }
 
+  public abstract class CellIdentity implements android.os.Parcelable {
+    method @NonNull public abstract android.telephony.CellLocation asCellLocation();
+  }
+
+  public final class CellIdentityCdma extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.cdma.CdmaCellLocation asCellLocation();
+  }
+
+  public final class CellIdentityGsm extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
+  }
+
+  public final class CellIdentityLte extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
+  }
+
+  public final class CellIdentityNr extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.CellLocation asCellLocation();
+  }
+
+  public final class CellIdentityTdscdma extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
+  }
+
+  public final class CellIdentityWcdma extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
+  }
+
   public final class DataFailCause {
     field public static final int ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 2219; // 0x8ab
     field public static final int ACCESS_BLOCK = 2087; // 0x827
@@ -9580,6 +9608,7 @@
   }
 
   public final class PreciseCallState implements android.os.Parcelable {
+    ctor public PreciseCallState(int, int, int, int, int);
     method public int describeContents();
     method public int getBackgroundCallState();
     method public int getForegroundCallState();
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 68bdfae..3f9f7fb 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -4547,4 +4547,17 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Method for the app to tell system that it's wedged and would like to trigger an ANR.
+     *
+     * @param reason The description of that what happened
+     */
+    public void appNotResponding(@NonNull final String reason) {
+        try {
+            getService().appNotResponding(reason);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 112bd30..e8494c4 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -583,4 +583,9 @@
      * unlockProgressListener can be null if monitoring progress is not necessary.
      */
     boolean startUserInForegroundWithListener(int userid, IProgressListener unlockProgressListener);
+
+    /**
+     * Method for the app to tell system that it's wedged and would like to trigger an ANR.
+     */
+    void appNotResponding(String reason);
 }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index c5a147a..7967708 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -11050,6 +11050,7 @@
                 case ACTION_MEDIA_SCANNER_FINISHED:
                 case ACTION_MEDIA_SCANNER_SCAN_FILE:
                 case ACTION_PACKAGE_NEEDS_VERIFICATION:
+                case ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION:
                 case ACTION_PACKAGE_VERIFIED:
                 case ACTION_PACKAGE_ENABLE_ROLLBACK:
                     // Ignore legacy actions
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index 51a9c86..e5f2c3a 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -24,7 +24,6 @@
 import android.annotation.UnsupportedAppUsage;
 import android.os.Binder;
 import android.os.Build;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerExecutor;
 import android.os.Looper;
@@ -993,8 +992,11 @@
                     () -> mExecutor.execute(() -> psl.onCallForwardingIndicatorChanged(cfi)));
         }
 
-        public void onCellLocationChanged(Bundle bundle) {
-            CellLocation location = CellLocation.newFromBundle(bundle);
+        public void onCellLocationChanged(CellIdentity cellIdentity) {
+            // There is no system/public API to create an CellIdentity in system server,
+            // so the server pass a null to indicate an empty initial location.
+            CellLocation location =
+                    cellIdentity == null ? CellLocation.getEmpty() : cellIdentity.asCellLocation();
             PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
             if (psl == null) return;
 
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index f574160..1b2feda 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -22,7 +22,6 @@
 import android.annotation.TestApi;
 import android.content.Context;
 import android.os.Binder;
-import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.telephony.Annotation.CallState;
@@ -633,10 +632,14 @@
     }
 
     /**
-     * TODO change from bundle to CellLocation?
+     * Notify {@link android.telephony.CellLocation} changed.
+     *
+     * <p>To be compatible with {@link TelephonyRegistry}, use {@link CellIdentity} which is
+     * parcelable, and convert to CellLocation in client code.
+     *
      * @hide
      */
-    public void notifyCellLocation(int subId, Bundle cellLocation) {
+    public void notifyCellLocation(int subId, CellIdentity cellLocation) {
         try {
             sRegistry.notifyCellLocationForSubscriber(subId, cellLocation);
         } catch (RemoteException ex) {
diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
index cb67309..6c7e3dc 100644
--- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -16,8 +16,8 @@
 
 package com.android.internal.telephony;
 
-import android.os.Bundle;
 import android.telephony.CallAttributes;
+import android.telephony.CellIdentity;
 import android.telephony.CellInfo;
 import android.telephony.DataConnectionRealTimeInfo;
 import android.telephony.PhoneCapability;
@@ -37,8 +37,8 @@
     void onMessageWaitingIndicatorChanged(boolean mwi);
     void onCallForwardingIndicatorChanged(boolean cfi);
 
-    // we use bundle here instead of CellLocation so it can get the right subclass
-    void onCellLocationChanged(in Bundle location);
+    // Uses CellIdentity which is Parcelable here; will convert to CellLocation in client.
+    void onCellLocationChanged(in CellIdentity location);
     void onCallStateChanged(int state, String incomingNumber);
     void onDataConnectionStateChanged(int state, int networkType);
     void onDataActivity(int direction);
@@ -63,4 +63,3 @@
     void onCallDisconnectCauseChanged(in int disconnectCause, in int preciseDisconnectCause);
     void onImsCallDisconnectCauseChanged(in ImsReasonInfo imsReasonInfo);
 }
-
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index f954679..4e40503 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -19,8 +19,8 @@
 import android.content.Intent;
 import android.net.LinkProperties;
 import android.net.NetworkCapabilities;
-import android.os.Bundle;
 import android.telephony.CallQuality;
+import android.telephony.CellIdentity;
 import android.telephony.CellInfo;
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.PhoneCapability;
@@ -66,9 +66,9 @@
             int phoneId, int subId, String apnType, in PreciseDataConnectionState preciseState);
     @UnsupportedAppUsage
     void notifyDataConnectionFailed(String apnType);
-    @UnsupportedAppUsage(maxTargetSdk = 28)
-    void notifyCellLocation(in Bundle cellLocation);
-    void notifyCellLocationForSubscriber(in int subId, in Bundle cellLocation);
+    // Uses CellIdentity which is Parcelable here; will convert to CellLocation in client.
+    void notifyCellLocation(in CellIdentity cellLocation);
+    void notifyCellLocationForSubscriber(in int subId, in CellIdentity cellLocation);
     @UnsupportedAppUsage
     void notifyCellInfo(in List<CellInfo> cellInfo);
     void notifyPreciseCallState(int phoneId, int subId, int ringingCallState,
diff --git a/core/tests/overlaytests/device/res/layout/layout.xml b/core/tests/overlaytests/device/res/layout/layout.xml
new file mode 100644
index 0000000..e12c715
--- /dev/null
+++ b/core/tests/overlaytests/device/res/layout/layout.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 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.
+  -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:app="http://schemas.android.com/apk/res-auto"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <LinearLayout android:id="@id/view_1"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+        <com.android.overlaytest.view.TestTextView
+            android:id="@id/view_2"
+            android:layout_width="match_parent"
+            android:layout_height="100dp"
+            app:customAttribute="none"/>
+
+        <com.android.overlaytest.view.TestTextView
+            android:id="@id/view_3"
+            android:layout_width="match_parent"
+            android:layout_height="100dp"
+            app:customAttribute="none" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/core/tests/overlaytests/device/res/values/config.xml b/core/tests/overlaytests/device/res/values/config.xml
index c692a26..e918268 100644
--- a/core/tests/overlaytests/device/res/values/config.xml
+++ b/core/tests/overlaytests/device/res/values/config.xml
@@ -56,4 +56,16 @@
         <item>17</item>
         <item>19</item>
     </integer-array>
+
+    <attr name="customAttribute" />
+    <id name="view_1" />
+    <id name="view_2" />
+    <id name="view_3" />
+
+    <!-- Stabilize the ids of attributes and ids used in test layouts so that they differ from the
+     overlay resource ids -->
+    <public type="attr" name="customAttribute" id="0x7f200000"/>
+    <public type="id" name="view_1" id="0x7f210000"/>
+    <public type="id" name="view_2" id="0x7f210001"/>
+    <public type="id" name="view_3" id="0x7f210002"/>
 </resources>
diff --git a/core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java b/core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java
index fdb6bbb..636f4c8 100644
--- a/core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java
+++ b/core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java
@@ -18,20 +18,26 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.content.Context;
 import android.content.res.AssetManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.os.LocaleList;
 import android.util.AttributeSet;
+import android.util.TypedValue;
 import android.util.Xml;
+import android.view.LayoutInflater;
+import android.view.View;
 
 import androidx.test.InstrumentationRegistry;
 
 import com.android.internal.util.ArrayUtils;
+import com.android.overlaytest.view.TestTextView;
 
 import org.junit.Before;
 import org.junit.Ignore;
@@ -45,6 +51,7 @@
 
 @Ignore
 public abstract class OverlayBaseTest {
+    private Context mContext;
     private Resources mResources;
     private final int mMode;
     static final int MODE_NO_OVERLAY = 0;
@@ -61,7 +68,8 @@
 
     @Before
     public void setUp() {
-        mResources = InstrumentationRegistry.getContext().getResources();
+        mContext = InstrumentationRegistry.getContext();
+        mResources = mContext.getResources();
     }
 
     private int calculateRawResourceChecksum(int resId) throws Throwable {
@@ -321,6 +329,50 @@
         assertEquals("com.android.overlaytest", contents);
     }
 
+    @Test
+    public void testRewrite() throws Throwable {
+        final TypedValue result = new TypedValue();
+        mResources.getValue(R.string.str, result, true);
+        assertEquals(result.resourceId & 0xff000000, 0x7f000000);
+    }
+
+    @Test
+    public void testOverlayLayout() throws Throwable {
+        final LayoutInflater inflater = LayoutInflater.from(mContext);
+        final View layout = inflater.inflate(R.layout.layout, null);
+        assertNotNull(layout.findViewById(R.id.view_1));
+
+        final TestTextView view2 = layout.findViewById(R.id.view_2);
+        assertNotNull(view2);
+        switch (mMode) {
+            case MODE_NO_OVERLAY:
+                assertEquals("none", view2.getCustomAttributeValue());
+                break;
+            case MODE_SINGLE_OVERLAY:
+                assertEquals("single", view2.getCustomAttributeValue());
+                break;
+            case MODE_MULTIPLE_OVERLAYS:
+                assertEquals("multiple", view2.getCustomAttributeValue());
+                break;
+            default:
+                fail("Unknown mode " + mMode);
+        }
+
+        final TestTextView view3 = layout.findViewById(R.id.view_3);
+        assertNotNull(view3);
+        switch (mMode) {
+            case MODE_NO_OVERLAY:
+                assertEquals("none", view3.getCustomAttributeValue());
+                break;
+            case MODE_SINGLE_OVERLAY:
+            case MODE_MULTIPLE_OVERLAYS:
+                assertEquals("overlaid", view3.getCustomAttributeValue());
+                break;
+            default:
+                fail("Unknown mode " + mMode);
+        }
+    }
+
     /*
      * testMatrix* tests
      *
diff --git a/core/tests/overlaytests/device/src/com/android/overlaytest/view/TestTextView.java b/core/tests/overlaytests/device/src/com/android/overlaytest/view/TestTextView.java
new file mode 100644
index 0000000..2245e2b
--- /dev/null
+++ b/core/tests/overlaytests/device/src/com/android/overlaytest/view/TestTextView.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 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.overlaytest.view;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+public class TestTextView extends TextView {
+
+    private final String mCustomAttributeValue;
+
+    public TestTextView(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.textViewStyle, 0);
+    }
+
+    public TestTextView(Context context, AttributeSet attrs,
+            int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        int[] testResources = new int[]{com.android.overlaytest.R.attr.customAttribute};
+        final Resources.Theme theme = context.getTheme();
+        TypedArray typedArray = theme.obtainStyledAttributes(attrs, testResources, defStyleAttr,
+                defStyleRes);
+        mCustomAttributeValue = typedArray.getString(0);
+    }
+
+    public String getCustomAttributeValue() {
+        return mCustomAttributeValue;
+    }
+}
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayOne/AndroidManifest.xml b/core/tests/overlaytests/device/test-apps/AppOverlayOne/AndroidManifest.xml
index 7d28408..873ca3c 100644
--- a/core/tests/overlaytests/device/test-apps/AppOverlayOne/AndroidManifest.xml
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayOne/AndroidManifest.xml
@@ -19,5 +19,6 @@
         android:versionCode="1"
         android:versionName="1.0">
         <application android:hasCode="false" />
-        <overlay android:targetPackage="com.android.overlaytest" />
+        <overlay android:targetPackage="com.android.overlaytest"
+                 android:resourcesMap="@xml/overlays"/>
 </manifest>
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/layout/layout.xml b/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/layout/layout.xml
new file mode 100644
index 0000000..7b63605
--- /dev/null
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/layout/layout.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 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.
+  -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:app="http://schemas.android.com/apk/res-auto"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <LinearLayout android:id="@+id/view_1"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+        <com.android.overlaytest.view.TestTextView
+            android:id="@+id/view_2"
+            android:layout_width="match_parent"
+            android:layout_height="100dp"
+            app:customAttribute="@string/str" />
+
+        <com.android.overlaytest.view.TestTextView
+            android:id="@+id/view_3"
+            android:layout_width="match_parent"
+            android:layout_height="100dp"
+            app:customAttribute="overlaid" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/values/config.xml b/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/values/config.xml
index 972137a..74c4963 100644
--- a/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/values/config.xml
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/values/config.xml
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
     <string name="str">single</string>
-    <string name="str2">single</string>
     <integer name="matrix_101000">300</integer>
     <integer name="matrix_101001">300</integer>
     <integer name="matrix_101010">300</integer>
@@ -18,7 +17,6 @@
     <integer name="matrix_111101">300</integer>
     <integer name="matrix_111110">300</integer>
     <integer name="matrix_111111">300</integer>
-    <bool name="usually_false">true</bool>
     <integer-array name="fibonacci">
         <item>21</item>
         <item>13</item>
@@ -29,7 +27,10 @@
         <item>1</item>
         <item>1</item>
     </integer-array>
+
     <!-- The following integer does not exist in the original package. Idmap
          generation should therefore ignore it. -->
     <integer name="integer_not_in_original_package">0</integer>
+
+    <attr name="customAttribute" />
 </resources>
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/xml/overlays.xml b/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/xml/overlays.xml
new file mode 100644
index 0000000..38e5fa1
--- /dev/null
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/xml/overlays.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 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.
+  -->
+<overlay>
+    <item target="drawable/drawable" value="@drawable/drawable"/>
+    <item target="layout/layout" value="@layout/layout"/>
+    <item target="raw/lorem_ipsum" value="@raw/lorem_ipsum"/>
+    <item target="xml/integer" value="@xml/integer"/>
+    <item target="string/str" value="@string/str"/>
+    <item target="string/str2" value="single"/>
+
+    <item target="integer/matrix_100100" value="@integer/matrix_100100"/>
+    <item target="integer/matrix_100101" value="@integer/matrix_100101"/>
+    <item target="integer/matrix_100110" value="@integer/matrix_100110"/>
+    <item target="integer/matrix_100110" value="@integer/matrix_100110"/>
+    <item target="integer/matrix_100111" value="@integer/matrix_100111"/>
+    <item target="integer/matrix_101000" value="@integer/matrix_101000"/>
+    <item target="integer/matrix_101001" value="@integer/matrix_101001"/>
+    <item target="integer/matrix_101010" value="@integer/matrix_101010"/>
+    <item target="integer/matrix_101011" value="@integer/matrix_101011"/>
+    <item target="integer/matrix_101100" value="@integer/matrix_101100"/>
+    <item target="integer/matrix_101101" value="@integer/matrix_101101"/>
+    <item target="integer/matrix_101110" value="@integer/matrix_101110"/>
+    <item target="integer/matrix_101111" value="@integer/matrix_101111"/>
+    <item target="integer/matrix_110100" value="@integer/matrix_110100"/>
+    <item target="integer/matrix_110101" value="@integer/matrix_110101"/>
+    <item target="integer/matrix_110110" value="@integer/matrix_110110"/>
+    <item target="integer/matrix_110111" value="@integer/matrix_110111"/>
+    <item target="integer/matrix_111000" value="@integer/matrix_111000"/>
+    <item target="integer/matrix_111001" value="@integer/matrix_111001"/>
+    <item target="integer/matrix_111010" value="@integer/matrix_111010"/>
+    <item target="integer/matrix_111011" value="@integer/matrix_111011"/>
+    <item target="integer/matrix_111100" value="@integer/matrix_111100"/>
+    <item target="integer/matrix_111101" value="@integer/matrix_111101"/>
+    <item target="integer/matrix_111110" value="@integer/matrix_111110"/>
+    <item target="integer/matrix_111111" value="@integer/matrix_111111"/>
+
+    <item target="bool/usually_false" value="true"/>
+
+    <item target="array/fibonacci" value="@array/fibonacci"/>
+
+    <item target="attr/customAttribute" value="@attr/customAttribute"/>
+    <item target="id/view_1" value="@id/view_1"/>
+    <item target="id/view_2" value="@id/view_2"/>
+    <item target="id/view_3" value="@id/view_3"/>
+</overlay>
+
+
diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp
index ce3bfff..0b2fd9e 100644
--- a/libs/androidfw/Idmap.cpp
+++ b/libs/androidfw/Idmap.cpp
@@ -57,7 +57,7 @@
 
 const char16_t* OverlayStringPool::stringAt(size_t idx, size_t* outLen) const {
   const size_t offset = dtohl(data_header_->string_pool_index_offset);
-  if (idmap_string_pool_ != nullptr && idx >= size() && idx >= offset) {
+  if (idmap_string_pool_ != nullptr && idx >= ResStringPool::size() && idx >= offset) {
     return idmap_string_pool_->stringAt(idx - offset, outLen);
   }
 
@@ -66,13 +66,17 @@
 
 const char* OverlayStringPool::string8At(size_t idx, size_t* outLen) const {
   const size_t offset = dtohl(data_header_->string_pool_index_offset);
-  if (idmap_string_pool_ != nullptr && idx >= size() && idx >= offset) {
+  if (idmap_string_pool_ != nullptr && idx >= ResStringPool::size() && idx >= offset) {
     return idmap_string_pool_->string8At(idx - offset, outLen);
   }
 
   return ResStringPool::string8At(idx, outLen);
 }
 
+size_t OverlayStringPool::size() const {
+  return ResStringPool::size() + (idmap_string_pool_ != nullptr ? idmap_string_pool_->size() : 0U);
+}
+
 OverlayDynamicRefTable::OverlayDynamicRefTable(const Idmap_data_header* data_header,
                                                const Idmap_overlay_entry* entries,
                                                uint8_t target_assigned_package_id)
diff --git a/libs/androidfw/include/androidfw/Idmap.h b/libs/androidfw/include/androidfw/Idmap.h
index ab4c9c2..ccb57f3 100644
--- a/libs/androidfw/include/androidfw/Idmap.h
+++ b/libs/androidfw/include/androidfw/Idmap.h
@@ -40,8 +40,9 @@
 class OverlayStringPool : public ResStringPool {
  public:
   virtual ~OverlayStringPool();
-  virtual const char16_t* stringAt(size_t idx, size_t* outLen) const;
-  virtual const char* string8At(size_t idx, size_t* outLen) const;
+  const char16_t* stringAt(size_t idx, size_t* outLen) const override;
+  const char* string8At(size_t idx, size_t* outLen) const override;
+  size_t size() const override;
 
   explicit OverlayStringPool(const LoadedIdmap* loaded_idmap);
  private:
@@ -53,8 +54,8 @@
 // resources to the resource id of corresponding target resources.
 class OverlayDynamicRefTable : public DynamicRefTable {
  public:
-  virtual ~OverlayDynamicRefTable() = default;
-  virtual status_t lookupResourceId(uint32_t* resId) const;
+  ~OverlayDynamicRefTable() override = default;
+  status_t lookupResourceId(uint32_t* resId) const override;
 
  private:
   explicit OverlayDynamicRefTable(const Idmap_data_header* data_header,
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index b603326..35cebd4 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -520,7 +520,7 @@
 
     ssize_t indexOfString(const char16_t* str, size_t strLen) const;
 
-    size_t size() const;
+    virtual size_t size() const;
     size_t styleCount() const;
     size_t bytes() const;
     const void* data() const;
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index f363a73..40a7dfc 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -67,6 +67,27 @@
     public static final int PACKAGE_COMPANION = 14;
 
     @IntDef(value = {
+            INTEGRITY_VERIFICATION_ALLOW,
+            INTEGRITY_VERIFICATION_REJECT,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface IntegrityVerificationResult {}
+
+    /**
+     * Used as the {@code verificationCode} argument for
+     * {@link PackageManagerInternal#setIntegrityVerificationResult(int, int)} to indicate that the
+     * integrity component allows the install to proceed.
+     */
+    public static final int INTEGRITY_VERIFICATION_ALLOW = 1;
+
+    /**
+     * Used as the {@code verificationCode} argument for
+     * {@link PackageManagerInternal#setIntegrityVerificationResult(int, int)} to indicate that the
+     * integrity component does not allow install to proceed.
+     */
+    public static final int INTEGRITY_VERIFICATION_REJECT = 0;
+
+    @IntDef(value = {
         PACKAGE_SYSTEM,
         PACKAGE_SETUP_WIZARD,
         PACKAGE_INSTALLER,
@@ -842,13 +863,13 @@
      * {@link Intent#ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION package verification
      * broadcast} to respond to the package manager. The response must include
      * the {@code verificationCode} which is one of
-     * {@link PackageManager#VERIFICATION_ALLOW} or
-     * {@link PackageManager#VERIFICATION_REJECT}.
+     * {@link #INTEGRITY_VERIFICATION_ALLOW} and {@link #INTEGRITY_VERIFICATION_REJECT}.
      *
      * @param verificationId pending package identifier as passed via the
      *            {@link PackageManager#EXTRA_VERIFICATION_ID} Intent extra.
-     * @param verificationResult either {@link PackageManager#VERIFICATION_ALLOW}
-     *            or {@link PackageManager#VERIFICATION_REJECT}.
+     * @param verificationResult either {@link #INTEGRITY_VERIFICATION_ALLOW}
+     *            or {@link #INTEGRITY_VERIFICATION_REJECT}.
      */
-    public abstract void setIntegrityVerificationResult(int verificationId, int verificationResult);
+    public abstract void setIntegrityVerificationResult(int verificationId,
+            @IntegrityVerificationResult int verificationResult);
 }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 13eb556..46ff718 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -46,6 +46,7 @@
 import android.telephony.Annotation.SrvccState;
 import android.telephony.CallAttributes;
 import android.telephony.CallQuality;
+import android.telephony.CellIdentity;
 import android.telephony.CellInfo;
 import android.telephony.CellLocation;
 import android.telephony.DataFailCause;
@@ -207,7 +208,7 @@
     // Connection state of default APN type data (i.e. internet) of phones
     private int[] mDataConnectionState;
 
-    private Bundle[] mCellLocation;
+    private CellIdentity[] mCellIdentity;
 
     private int[] mDataConnectionNetworkType;
 
@@ -295,7 +296,7 @@
                     int numPhones = getTelephonyManager().getPhoneCount();
                     for (int sub = 0; sub < numPhones; sub++) {
                         TelephonyRegistry.this.notifyCellLocationForSubscriber(sub,
-                                mCellLocation[sub]);
+                                mCellIdentity[sub]);
                     }
                     break;
                 }
@@ -404,7 +405,7 @@
         mSignalStrength = copyOf(mSignalStrength, mNumPhones);
         mMessageWaiting = copyOf(mMessageWaiting, mNumPhones);
         mCallForwarding = copyOf(mCallForwarding, mNumPhones);
-        mCellLocation = copyOf(mCellLocation, mNumPhones);
+        mCellIdentity = copyOf(mCellIdentity, mNumPhones);
         mSrvccState = copyOf(mSrvccState, mNumPhones);
         mPreciseCallState = copyOf(mPreciseCallState, mNumPhones);
         mForegroundCallState = copyOf(mForegroundCallState, mNumPhones);
@@ -439,31 +440,22 @@
             mUserMobileDataState[i] = false;
             mMessageWaiting[i] =  false;
             mCallForwarding[i] =  false;
-            mCellLocation[i] = new Bundle();
+            mCellIdentity[i] = null;
             mCellInfo.add(i, null);
             mImsReasonInfo.add(i, null);
             mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE;
             mCallDisconnectCause[i] = DisconnectCause.NOT_VALID;
             mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID;
             mCallQuality[i] = createCallQuality();
-            mCallAttributes[i] = new CallAttributes(new PreciseCallState(),
+            mCallAttributes[i] = new CallAttributes(createPreciseCallState(),
                     TelephonyManager.NETWORK_TYPE_UNKNOWN, createCallQuality());
             mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN;
-            mPreciseCallState[i] = new PreciseCallState();
+            mPreciseCallState[i] = createPreciseCallState();
             mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
             mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
             mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
             mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>());
         }
-
-        // Note that location can be null for non-phone builds like
-        // like the generic one.
-        CellLocation  location = CellLocation.getEmpty();
-        if (location != null) {
-            for (int i = oldNumPhones; i < mNumPhones; i++) {
-                location.fillInNotifierBundle(mCellLocation[i]);
-            }
-        }
     }
 
     private void cutListToSize(List list, int size) {
@@ -503,7 +495,7 @@
         mSignalStrength = new SignalStrength[numPhones];
         mMessageWaiting = new boolean[numPhones];
         mCallForwarding = new boolean[numPhones];
-        mCellLocation = new Bundle[numPhones];
+        mCellIdentity = new CellIdentity[numPhones];
         mSrvccState = new int[numPhones];
         mPreciseCallState = new PreciseCallState[numPhones];
         mForegroundCallState = new int[numPhones];
@@ -532,31 +524,23 @@
             mUserMobileDataState[i] = false;
             mMessageWaiting[i] =  false;
             mCallForwarding[i] =  false;
-            mCellLocation[i] = new Bundle();
+            mCellIdentity[i] = null;
             mCellInfo.add(i, null);
             mImsReasonInfo.add(i, null);
             mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE;
             mCallDisconnectCause[i] = DisconnectCause.NOT_VALID;
             mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID;
             mCallQuality[i] = createCallQuality();
-            mCallAttributes[i] = new CallAttributes(new PreciseCallState(),
+            mCallAttributes[i] = new CallAttributes(createPreciseCallState(),
                     TelephonyManager.NETWORK_TYPE_UNKNOWN, createCallQuality());
             mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN;
-            mPreciseCallState[i] = new PreciseCallState();
+            mPreciseCallState[i] = createPreciseCallState();
             mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
             mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
             mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
             mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>());
         }
 
-        // Note that location can be null for non-phone builds like
-        // like the generic one.
-        if (location != null) {
-            for (int i = 0; i < numPhones; i++) {
-                location.fillInNotifierBundle(mCellLocation[i]);
-            }
-        }
-
         mAppOps = mContext.getSystemService(AppOpsManager.class);
     }
 
@@ -837,11 +821,10 @@
                     }
                     if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
                         try {
-                            if (DBG_LOC) log("listen: mCellLocation = "
-                                    + mCellLocation[phoneId]);
+                            if (DBG_LOC) log("listen: mCellIdentity = " + mCellIdentity[phoneId]);
                             if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
-                                r.callback.onCellLocationChanged(
-                                        new Bundle(mCellLocation[phoneId]));
+                                // null will be translated to empty CellLocation object in client.
+                                r.callback.onCellLocationChanged(mCellIdentity[phoneId]);
                             }
                         } catch (RemoteException ex) {
                             remove(r.binder);
@@ -1629,11 +1612,13 @@
         broadcastDataConnectionFailed(apnType, subId);
     }
 
-    public void notifyCellLocation(Bundle cellLocation) {
-         notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellLocation);
+    @Override
+    public void notifyCellLocation(CellIdentity cellLocation) {
+        notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellLocation);
     }
 
-    public void notifyCellLocationForSubscriber(int subId, Bundle cellLocation) {
+    @Override
+    public void notifyCellLocationForSubscriber(int subId, CellIdentity cellLocation) {
         log("notifyCellLocationForSubscriber: subId=" + subId
                 + " cellLocation=" + cellLocation);
         if (!checkNotifyPermission("notifyCellLocation()")) {
@@ -1646,7 +1631,7 @@
         int phoneId = getPhoneIdFromSubId(subId);
         synchronized (mRecords) {
             if (validatePhoneId(phoneId)) {
-                mCellLocation[phoneId] = cellLocation;
+                mCellIdentity[phoneId] = cellLocation;
                 for (Record r : mRecords) {
                     if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) &&
                             idMatch(r.subId, subId, phoneId) &&
@@ -1656,7 +1641,7 @@
                                 log("notifyCellLocation: cellLocation=" + cellLocation
                                         + " r=" + r);
                             }
-                            r.callback.onCellLocationChanged(new Bundle(cellLocation));
+                            r.callback.onCellLocationChanged(cellLocation);
                         } catch (RemoteException ex) {
                             mRemoveList.add(r.binder);
                         }
@@ -2093,7 +2078,7 @@
                 pw.println("mCallForwarding=" + mCallForwarding[i]);
                 pw.println("mDataActivity=" + mDataActivity[i]);
                 pw.println("mDataConnectionState=" + mDataConnectionState[i]);
-                pw.println("mCellLocation=" + mCellLocation[i]);
+                pw.println("mCellIdentity=" + mCellIdentity[i]);
                 pw.println("mCellInfo=" + mCellInfo.get(i));
                 pw.println("mImsCallDisconnectCause=" + mImsReasonInfo.get(i));
                 pw.println("mSrvccState=" + mSrvccState[i]);
@@ -2583,10 +2568,13 @@
 
         if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
             try {
-                if (DBG_LOC) log("checkPossibleMissNotify: onCellLocationChanged mCellLocation = "
-                        + mCellLocation[phoneId]);
+                if (DBG_LOC) {
+                    log("checkPossibleMissNotify: onCellLocationChanged mCellIdentity = "
+                            + mCellIdentity[phoneId]);
+                }
                 if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
-                    r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId]));
+                    // null will be translated to empty CellLocation object in client.
+                    r.callback.onCellLocationChanged(mCellIdentity[phoneId]);
                 }
             } catch (RemoteException ex) {
                 mRemoveList.add(r.binder);
@@ -2678,6 +2666,15 @@
         }
     }
 
+    /** Returns a new PreciseCallState object with default values. */
+    private static PreciseCallState createPreciseCallState() {
+        return new PreciseCallState(PreciseCallState.PRECISE_CALL_STATE_NOT_VALID,
+            PreciseCallState.PRECISE_CALL_STATE_NOT_VALID,
+            PreciseCallState.PRECISE_CALL_STATE_NOT_VALID,
+            DisconnectCause.NOT_VALID,
+            PreciseDisconnectCause.NOT_VALID);
+    }
+
     /** Returns a new CallQuality object with default values. */
     private static CallQuality createCallQuality() {
         return new CallQuality(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6dc49b7..d7a46fe 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7558,6 +7558,26 @@
         });
     }
 
+    @Override
+    public void appNotResponding(final String reason) {
+        final int callingPid = Binder.getCallingPid();
+
+        synchronized (mPidsSelfLocked) {
+            final ProcessRecord app = mPidsSelfLocked.get(callingPid);
+            if (app == null) {
+                throw new SecurityException("Unknown process: " + callingPid);
+            }
+
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    app.appNotResponding(
+                            null, app.info, null, null, false, "App requested: " + reason);
+                }
+            });
+        }
+    }
+
     public final void installSystemProviders() {
         List<ProviderInfo> providers;
         synchronized (this) {
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 0b74840..9f23cdaf 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -2335,7 +2335,7 @@
             } else {
                 final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
                 final int mode = switchOp.evalMode();
-                if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
+                if (mode != AppOpsManager.MODE_ALLOWED) {
                     if (DEBUG) Slog.d(TAG, "noteOperation: reject #" + mode + " for code "
                             + switchCode + " (" + code + ") uid " + uid + " package "
                             + packageName);
diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
index 39c1b85..5c4479a 100644
--- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
+++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
@@ -23,7 +23,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -36,6 +35,8 @@
 class AppIntegrityManagerServiceImpl {
     private static final String TAG = "AppIntegrityManagerServiceImpl";
 
+    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
+
     private final Context mContext;
     private final Handler mHandler;
     private final PackageManagerInternal mPackageManagerInternal;
@@ -51,6 +52,11 @@
 
         IntentFilter integrityVerificationFilter = new IntentFilter();
         integrityVerificationFilter.addAction(ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
+        try {
+            integrityVerificationFilter.addDataType(PACKAGE_MIME_TYPE);
+        } catch (IntentFilter.MalformedMimeTypeException e) {
+            throw new RuntimeException("Mime type malformed: should never happen.", e);
+        }
 
         mContext.registerReceiver(
                 new BroadcastReceiver() {
@@ -74,7 +80,8 @@
         int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1);
         // TODO: implement this method.
         Slog.i(TAG, "Received integrity verification intent " + intent.toString());
+        Slog.i(TAG, "Extras " + intent.getExtras());
         mPackageManagerInternal.setIntegrityVerificationResult(
-                verificationId, PackageManager.VERIFICATION_ALLOW);
+                verificationId, PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
     }
 }
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java b/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java
index cfe50c6..ebf6a2e 100644
--- a/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java
+++ b/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java
@@ -16,6 +16,10 @@
 
 package com.android.server.integrity.serializer;
 
+import static com.android.server.integrity.serializer.RuleIndexingDetails.APP_CERTIFICATE_INDEXED;
+import static com.android.server.integrity.serializer.RuleIndexingDetails.NOT_INDEXED;
+import static com.android.server.integrity.serializer.RuleIndexingDetails.PACKAGE_NAME_INDEXED;
+
 import android.content.integrity.AtomicFormula;
 import android.content.integrity.CompoundFormula;
 import android.content.integrity.Formula;
@@ -29,6 +33,7 @@
 import java.io.StringWriter;
 import java.nio.charset.StandardCharsets;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 
 /** A helper class to serialize rules from the {@link Rule} model to Xml representation. */
@@ -75,13 +80,32 @@
         }
     }
 
-    private void serializeRules(List<Rule> rules, XmlSerializer xmlSerializer) throws IOException {
-        xmlSerializer.startTag(NAMESPACE, RULE_LIST_TAG);
+    private void serializeRules(List<Rule> rules, XmlSerializer xmlSerializer)
+            throws RuleSerializeException {
+        try {
+            // Determine the indexing groups and the order of the rules within each indexed group.
+            Map<Integer, List<Rule>> indexedRules =
+                    RuleIndexingDetailsIdentifier.splitRulesIntoIndexBuckets(rules);
+
+            // Write the XML formatted rules in order.
+            xmlSerializer.startTag(NAMESPACE, RULE_LIST_TAG);
+
+            serializeRuleList(indexedRules.get(PACKAGE_NAME_INDEXED), xmlSerializer);
+            serializeRuleList(indexedRules.get(APP_CERTIFICATE_INDEXED), xmlSerializer);
+            serializeRuleList(indexedRules.get(NOT_INDEXED), xmlSerializer);
+
+            xmlSerializer.endTag(NAMESPACE, RULE_LIST_TAG);
+            xmlSerializer.endDocument();
+        } catch (Exception e) {
+            throw new RuleSerializeException(e.getMessage(), e);
+        }
+    }
+
+    private void serializeRuleList(List<Rule> rules, XmlSerializer xmlSerializer)
+            throws IOException {
         for (Rule rule : rules) {
             serializeRule(rule, xmlSerializer);
         }
-        xmlSerializer.endTag(NAMESPACE, RULE_LIST_TAG);
-        xmlSerializer.endDocument();
     }
 
     private void serializeRule(Rule rule, XmlSerializer xmlSerializer) throws IOException {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 1a64166..785ca7d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -27,6 +27,8 @@
 import static android.content.Intent.ACTION_MAIN;
 import static android.content.Intent.CATEGORY_DEFAULT;
 import static android.content.Intent.CATEGORY_HOME;
+import static android.content.Intent.EXTRA_PACKAGE_NAME;
+import static android.content.Intent.EXTRA_VERSION_CODE;
 import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509;
 import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
@@ -34,6 +36,7 @@
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ID;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
@@ -558,6 +561,11 @@
     private static final boolean DEFAULT_VERIFY_ENABLE = true;
 
     /**
+     * Whether integrity verification is enabled by default.
+     */
+    private static final boolean DEFAULT_INTEGRITY_VERIFY_ENABLE = true;
+
+    /**
      * The default maximum time to wait for the verification agent to return in
      * milliseconds.
      */
@@ -1444,6 +1452,7 @@
     static final int DEFERRED_NO_KILL_POST_DELETE = 23;
     static final int DEFERRED_NO_KILL_INSTALL_OBSERVER = 24;
     static final int INTEGRITY_VERIFICATION_COMPLETE = 25;
+    static final int CHECK_PENDING_INTEGRITY_VERIFICATION = 26;
 
     static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
     static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
@@ -1707,13 +1716,13 @@
                     final int verificationId = msg.arg1;
                     final PackageVerificationState state = mPendingVerification.get(verificationId);
 
-                    if ((state != null) && !state.timeoutExtended()) {
+                    if ((state != null) && !state.isVerificationComplete()
+                            && !state.timeoutExtended()) {
                         final InstallParams params = state.getInstallParams();
                         final InstallArgs args = params.mArgs;
                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
 
                         Slog.i(TAG, "Verification timed out for " + originUri);
-                        mPendingVerification.remove(verificationId);
 
                         final UserHandle user = args.getUser();
                         if (getDefaultVerificationResponse(user)
@@ -1728,11 +1737,54 @@
                                     PackageManager.VERIFICATION_REJECT, user);
                             params.setReturnCode(
                                     PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
+                            state.setVerifierResponse(Binder.getCallingUid(),
+                                    PackageManager.VERIFICATION_REJECT);
+                        }
+
+                        if (state.areAllVerificationsComplete()) {
+                            mPendingVerification.remove(verificationId);
                         }
 
                         Trace.asyncTraceEnd(
                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
+
                         params.handleVerificationFinished();
+
+                    }
+                    break;
+                }
+                case CHECK_PENDING_INTEGRITY_VERIFICATION: {
+                    final int verificationId = msg.arg1;
+                    final PackageVerificationState state = mPendingVerification.get(verificationId);
+
+                    if (state != null && !state.isIntegrityVerificationComplete()) {
+                        final InstallParams params = state.getInstallParams();
+                        final InstallArgs args = params.mArgs;
+                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
+
+                        Slog.i(TAG, "Integrity verification timed out for " + originUri);
+
+                        state.setIntegrityVerificationResult(
+                                getDefaultIntegrityVerificationResponse());
+
+                        if (getDefaultIntegrityVerificationResponse()
+                                == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) {
+                            Slog.i(TAG, "Integrity check times out, continuing with " + originUri);
+                        } else {
+                            params.setReturnCode(
+                                    PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
+                        }
+
+                        if (state.areAllVerificationsComplete()) {
+                            mPendingVerification.remove(verificationId);
+                        }
+
+                        Trace.asyncTraceEnd(
+                                TRACE_TAG_PACKAGE_MANAGER,
+                                "integrity_verification",
+                                verificationId);
+
+                        params.handleIntegrityVerificationFinished();
                     }
                     break;
                 }
@@ -1741,7 +1793,9 @@
 
                     final PackageVerificationState state = mPendingVerification.get(verificationId);
                     if (state == null) {
-                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
+                        Slog.w(TAG, "Verification with id " + verificationId
+                                + " not found."
+                                + " It may be invalid or overridden by integrity verification");
                         break;
                     }
 
@@ -1750,8 +1804,6 @@
                     state.setVerifierResponse(response.callerUid, response.code);
 
                     if (state.isVerificationComplete()) {
-                        mPendingVerification.remove(verificationId);
-
                         final InstallParams params = state.getInstallParams();
                         final InstallArgs args = params.mArgs;
                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
@@ -1764,6 +1816,10 @@
                                     PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
                         }
 
+                        if (state.areAllVerificationsComplete()) {
+                            mPendingVerification.remove(verificationId);
+                        }
+
                         Trace.asyncTraceEnd(
                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
 
@@ -1773,7 +1829,40 @@
                     break;
                 }
                 case INTEGRITY_VERIFICATION_COMPLETE: {
-                    // TODO: implement this case.
+                    final int verificationId = msg.arg1;
+
+                    final PackageVerificationState state = mPendingVerification.get(verificationId);
+                    if (state == null) {
+                        Slog.w(TAG, "Integrity verification with id " + verificationId
+                                + " not found. It may be invalid or overridden by verifier");
+                        break;
+                    }
+
+                    final int response = (Integer) msg.obj;
+
+                    final InstallParams params = state.getInstallParams();
+                    final InstallArgs args = params.mArgs;
+                    final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
+
+                    state.setIntegrityVerificationResult(response);
+
+                    if (response == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) {
+                        Slog.i(TAG, "Integrity check passed for " + originUri);
+                    } else {
+                        params.setReturnCode(
+                                PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
+                    }
+
+                    if (state.areAllVerificationsComplete()) {
+                        mPendingVerification.remove(verificationId);
+                    }
+
+                    Trace.asyncTraceEnd(
+                            TRACE_TAG_PACKAGE_MANAGER,
+                            "integrity_verification",
+                            verificationId);
+
+                    params.handleIntegrityVerificationFinished();
                     break;
                 }
                 case START_INTENT_FILTER_VERIFICATIONS: {
@@ -13099,6 +13188,15 @@
     }
 
     /**
+     * Get the default integrity verification response code.
+     */
+    private int getDefaultIntegrityVerificationResponse() {
+        // We are not exposing this as a user-configurable setting because we don't want to provide
+        // an easy way to get around the integrity check.
+        return PackageManager.VERIFICATION_REJECT;
+    }
+
+    /**
      * Check whether or not package verification has been enabled.
      *
      * @return true if verification should be performed
@@ -13141,6 +13239,15 @@
         }
     }
 
+    /**
+     * Check whether or not integrity verification has been enabled.
+     */
+    private boolean isIntegrityVerificationEnabled() {
+        // We are not exposing this as a user-configurable setting because we don't want to provide
+        // an easy way to get around the integrity check.
+        return DEFAULT_INTEGRITY_VERIFY_ENABLE;
+    }
+
     @Override
     public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
             throws RemoteException {
@@ -13851,6 +13958,7 @@
         @NonNull final InstallSource installSource;
         final String volumeUuid;
         private boolean mVerificationCompleted;
+        private boolean mIntegrityVerificationCompleted;
         private boolean mEnableRollbackCompleted;
         private InstallArgs mArgs;
         int mRet;
@@ -14112,155 +14220,30 @@
 
             final InstallArgs args = createInstallArgs(this);
             mVerificationCompleted = true;
+            mIntegrityVerificationCompleted = true;
             mEnableRollbackCompleted = true;
             mArgs = args;
 
             if (ret == PackageManager.INSTALL_SUCCEEDED) {
-                // TODO: http://b/22976637
-                // Apps installed for "all" users use the device owner to verify the app
-                UserHandle verifierUser = getUser();
-                if (verifierUser == UserHandle.ALL) {
-                    verifierUser = UserHandle.SYSTEM;
-                }
+                final int verificationId = mPendingVerificationToken++;
 
-                /*
-                 * Determine if we have any installed package verifiers. If we
-                 * do, then we'll defer to them to verify the packages.
-                 */
-                final int requiredUid = mRequiredVerifierPackage == null ? -1
-                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
-                                verifierUser.getIdentifier());
-                final int installerUid =
-                        verificationInfo == null ? -1 : verificationInfo.installerUid;
-                if (!origin.existing && requiredUid != -1
-                        && isVerificationEnabled(
-                                verifierUser.getIdentifier(), installFlags, installerUid)) {
-                    final Intent verification = new Intent(
-                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
-                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
-                            PACKAGE_MIME_TYPE);
-                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-
-                    // Query all live verifiers based on current user state
-                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
-                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
-                            false /*allowDynamicSplits*/);
-
-                    if (DEBUG_VERIFY) {
-                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
-                                + verification.toString() + " with " + pkgLite.verifiers.length
-                                + " optional verifiers");
-                    }
-
-                    final int verificationId = mPendingVerificationToken++;
-
-                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
-
-                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
-                            installSource.initiatingPackageName);
-
-                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
-                            installFlags);
-
-                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
-                            pkgLite.packageName);
-
-                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
-                            pkgLite.versionCode);
-
-                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
-                            pkgLite.getLongVersionCode());
-
-                    if (verificationInfo != null) {
-                        if (verificationInfo.originatingUri != null) {
-                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
-                                    verificationInfo.originatingUri);
-                        }
-                        if (verificationInfo.referrer != null) {
-                            verification.putExtra(Intent.EXTRA_REFERRER,
-                                    verificationInfo.referrer);
-                        }
-                        if (verificationInfo.originatingUid >= 0) {
-                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
-                                    verificationInfo.originatingUid);
-                        }
-                        if (verificationInfo.installerUid >= 0) {
-                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
-                                    verificationInfo.installerUid);
-                        }
-                    }
-
-                    final PackageVerificationState verificationState = new PackageVerificationState(
-                            requiredUid, this);
-
+                // Perform package verification (unless we are simply moving the package).
+                if (!origin.existing) {
+                    PackageVerificationState verificationState =
+                            new PackageVerificationState(this);
                     mPendingVerification.append(verificationId, verificationState);
 
-                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
-                            receivers, verificationState);
+                    sendIntegrityVerificationRequest(verificationId, pkgLite, verificationState);
+                    ret = sendPackageVerificationRequest(
+                            verificationId, pkgLite, verificationState);
 
-                    DeviceIdleInternal idleController =
-                            mInjector.getLocalDeviceIdleController();
-                    final long idleDuration = getVerificationTimeout();
-
-                    /*
-                     * If any sufficient verifiers were listed in the package
-                     * manifest, attempt to ask them.
-                     */
-                    if (sufficientVerifiers != null) {
-                        final int N = sufficientVerifiers.size();
-                        if (N == 0) {
-                            Slog.i(TAG, "Additional verifiers required, but none installed.");
-                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
-                        } else {
-                            for (int i = 0; i < N; i++) {
-                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
-                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
-                                        verifierComponent.getPackageName(), idleDuration,
-                                        verifierUser.getIdentifier(), false, "package verifier");
-
-                                final Intent sufficientIntent = new Intent(verification);
-                                sufficientIntent.setComponent(verifierComponent);
-                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
-                            }
-                        }
-                    }
-
-                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
-                            mRequiredVerifierPackage, receivers);
-                    if (ret == PackageManager.INSTALL_SUCCEEDED
-                            && mRequiredVerifierPackage != null) {
-                        Trace.asyncTraceBegin(
-                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
-                        /*
-                         * Send the intent to the required verification agent,
-                         * but only start the verification timeout after the
-                         * target BroadcastReceivers have run.
-                         */
-                        verification.setComponent(requiredVerifierComponent);
-                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
-                                mRequiredVerifierPackage, idleDuration,
-                                verifierUser.getIdentifier(), false, "package verifier");
-                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
-                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
-                                new BroadcastReceiver() {
-                                    @Override
-                                    public void onReceive(Context context, Intent intent) {
-                                        final Message msg = mHandler
-                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
-                                        msg.arg1 = verificationId;
-                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
-                                    }
-                                }, null, 0, null, null);
-
-                        /*
-                         * We don't want the copy to proceed until verification
-                         * succeeds.
-                         */
-                        mVerificationCompleted = false;
+                    // If both verifications are skipped, we should remove the state.
+                    if (verificationState.areAllVerificationsComplete()) {
+                        mPendingVerification.remove(verificationId);
                     }
                 }
 
+
                 if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
                     // TODO(ruhler) b/112431924: Don't do this in case of 'move'?
                     final int enableRollbackToken = mPendingEnableRollbackToken++;
@@ -14316,6 +14299,228 @@
             mRet = ret;
         }
 
+        /**
+         * Send a request to check the integrity of the package.
+         */
+        void sendIntegrityVerificationRequest(
+                int verificationId,
+                PackageInfoLite pkgLite,
+                PackageVerificationState verificationState) {
+            if (!isIntegrityVerificationEnabled()) {
+                // Consider the integrity check as passed.
+                verificationState.setIntegrityVerificationResult(
+                        PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
+                return;
+            }
+
+            final Intent integrityVerification =
+                    new Intent(Intent.ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
+
+            integrityVerification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
+                    PACKAGE_MIME_TYPE);
+
+            final int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
+                    | Intent.FLAG_RECEIVER_REGISTERED_ONLY
+                    | Intent.FLAG_RECEIVER_FOREGROUND;
+            integrityVerification.addFlags(flags);
+
+            integrityVerification.putExtra(EXTRA_VERIFICATION_ID, verificationId);
+            integrityVerification.putExtra(EXTRA_PACKAGE_NAME, pkgLite.packageName);
+            integrityVerification.putExtra(EXTRA_VERSION_CODE, pkgLite.versionCode);
+            populateInstallerExtras(integrityVerification);
+
+            // send to integrity component only.
+            integrityVerification.setPackage("android");
+
+            DeviceIdleInternal idleController =
+                    mInjector.getLocalDeviceIdleController();
+            final long idleDuration = getVerificationTimeout();
+
+            idleController.addPowerSaveTempWhitelistAppDirect(Process.myUid(),
+                     idleDuration,
+                    false, "integrity component");
+            mContext.sendOrderedBroadcastAsUser(integrityVerification, UserHandle.SYSTEM,
+                    /* receiverPermission= */ null,
+                    new BroadcastReceiver() {
+                        @Override
+                        public void onReceive(Context context, Intent intent) {
+                            final Message msg =
+                                    mHandler.obtainMessage(CHECK_PENDING_INTEGRITY_VERIFICATION);
+                            msg.arg1 = verificationId;
+                            // TODO: do we want to use the same timeout?
+                            mHandler.sendMessageDelayed(msg, getVerificationTimeout());
+                        }
+                    }, /* scheduler= */ null,
+                    /* initialCode= */ 0,
+                    /* initialData= */ null,
+                    /* initialExtras= */ null);
+
+            Trace.asyncTraceBegin(
+                    TRACE_TAG_PACKAGE_MANAGER, "integrity_verification", verificationId);
+
+            // stop the copy until verification succeeds.
+            mIntegrityVerificationCompleted = false;
+        }
+
+        /**
+         * Send a request to verifier(s) to verify the package if necessary, and return
+         * {@link PackageManager#INSTALL_SUCCEEDED} if succeeded.
+         */
+        int sendPackageVerificationRequest(
+                int verificationId,
+                PackageInfoLite pkgLite,
+                PackageVerificationState verificationState) {
+            int ret = INSTALL_SUCCEEDED;
+
+            // TODO: http://b/22976637
+            // Apps installed for "all" users use the device owner to verify the app
+            UserHandle verifierUser = getUser();
+            if (verifierUser == UserHandle.ALL) {
+                verifierUser = UserHandle.SYSTEM;
+            }
+
+            /*
+             * Determine if we have any installed package verifiers. If we
+             * do, then we'll defer to them to verify the packages.
+             */
+            final int requiredUid = mRequiredVerifierPackage == null ? -1
+                    : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
+                            verifierUser.getIdentifier());
+            verificationState.setRequiredVerifierUid(requiredUid);
+            final int installerUid =
+                    verificationInfo == null ? -1 : verificationInfo.installerUid;
+            if (!origin.existing && requiredUid != -1
+                    && isVerificationEnabled(
+                    verifierUser.getIdentifier(), installFlags, installerUid)) {
+                final Intent verification = new Intent(
+                        Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
+                verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+                verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
+                        PACKAGE_MIME_TYPE);
+                verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+                // Query all live verifiers based on current user state
+                final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
+                        PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
+                        false /*allowDynamicSplits*/);
+
+                if (DEBUG_VERIFY) {
+                    Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
+                            + verification.toString() + " with " + pkgLite.verifiers.length
+                            + " optional verifiers");
+                }
+
+                verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
+
+                verification.putExtra(
+                        PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, installFlags);
+
+                verification.putExtra(
+                        PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, pkgLite.packageName);
+
+                verification.putExtra(
+                        PackageManager.EXTRA_VERIFICATION_VERSION_CODE, pkgLite.versionCode);
+
+                verification.putExtra(
+                        PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
+                        pkgLite.getLongVersionCode());
+
+                populateInstallerExtras(verification);
+
+                final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
+                        receivers, verificationState);
+
+                DeviceIdleInternal idleController =
+                        mInjector.getLocalDeviceIdleController();
+                final long idleDuration = getVerificationTimeout();
+
+                /*
+                 * If any sufficient verifiers were listed in the package
+                 * manifest, attempt to ask them.
+                 */
+                if (sufficientVerifiers != null) {
+                    final int n = sufficientVerifiers.size();
+                    if (n == 0) {
+                        Slog.i(TAG, "Additional verifiers required, but none installed.");
+                        ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
+                    } else {
+                        for (int i = 0; i < n; i++) {
+                            final ComponentName verifierComponent = sufficientVerifiers.get(i);
+                            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
+                                    verifierComponent.getPackageName(), idleDuration,
+                                    verifierUser.getIdentifier(), false, "package verifier");
+
+                            final Intent sufficientIntent = new Intent(verification);
+                            sufficientIntent.setComponent(verifierComponent);
+                            mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
+                        }
+                    }
+                }
+
+                final ComponentName requiredVerifierComponent = matchComponentForVerifier(
+                        mRequiredVerifierPackage, receivers);
+                if (mRequiredVerifierPackage != null) {
+                    /*
+                     * Send the intent to the required verification agent,
+                     * but only start the verification timeout after the
+                     * target BroadcastReceivers have run.
+                     */
+                    verification.setComponent(requiredVerifierComponent);
+                    idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
+                            mRequiredVerifierPackage, idleDuration,
+                            verifierUser.getIdentifier(), false, "package verifier");
+                    mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
+                            android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
+                            new BroadcastReceiver() {
+                                @Override
+                                public void onReceive(Context context, Intent intent) {
+                                    final Message msg = mHandler
+                                            .obtainMessage(CHECK_PENDING_VERIFICATION);
+                                    msg.arg1 = verificationId;
+                                    mHandler.sendMessageDelayed(msg, getVerificationTimeout());
+                                }
+                            }, null, 0, null, null);
+
+                    Trace.asyncTraceBegin(
+                            TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
+
+                    /*
+                     * We don't want the copy to proceed until verification
+                     * succeeds.
+                     */
+                    mVerificationCompleted = false;
+                }
+            } else {
+                verificationState.setVerifierResponse(
+                        requiredUid, PackageManager.VERIFICATION_ALLOW);
+            }
+            return ret;
+        }
+
+        void populateInstallerExtras(Intent intent) {
+            intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
+                    installSource.initiatingPackageName);
+
+            if (verificationInfo != null) {
+                if (verificationInfo.originatingUri != null) {
+                    intent.putExtra(Intent.EXTRA_ORIGINATING_URI,
+                            verificationInfo.originatingUri);
+                }
+                if (verificationInfo.referrer != null) {
+                    intent.putExtra(Intent.EXTRA_REFERRER,
+                            verificationInfo.referrer);
+                }
+                if (verificationInfo.originatingUid >= 0) {
+                    intent.putExtra(Intent.EXTRA_ORIGINATING_UID,
+                            verificationInfo.originatingUid);
+                }
+                if (verificationInfo.installerUid >= 0) {
+                    intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
+                            verificationInfo.installerUid);
+                }
+            }
+        }
+
         void setReturnCode(int ret) {
             if (mRet == PackageManager.INSTALL_SUCCEEDED) {
                 // Only update mRet if it was previously INSTALL_SUCCEEDED to
@@ -14325,10 +14530,28 @@
         }
 
         void handleVerificationFinished() {
-            mVerificationCompleted = true;
-            handleReturnCode();
+            if (!mVerificationCompleted) {
+                mVerificationCompleted = true;
+                if (mIntegrityVerificationCompleted || mRet != INSTALL_SUCCEEDED) {
+                    mIntegrityVerificationCompleted = true;
+                    handleReturnCode();
+                }
+                // integrity verification still pending.
+            }
         }
 
+        void handleIntegrityVerificationFinished() {
+            if (!mIntegrityVerificationCompleted) {
+                mIntegrityVerificationCompleted = true;
+                if (mVerificationCompleted || mRet != INSTALL_SUCCEEDED) {
+                    mVerificationCompleted = true;
+                    handleReturnCode();
+                }
+                // verifier still pending
+            }
+        }
+
+
         void handleRollbackEnabled() {
             // TODO(ruhler) b/112431924: Consider halting the install if we
             // couldn't enable rollback.
@@ -14338,7 +14561,8 @@
 
         @Override
         void handleReturnCode() {
-            if (mVerificationCompleted && mEnableRollbackCompleted) {
+            if (mVerificationCompleted
+                    && mIntegrityVerificationCompleted && mEnableRollbackCompleted) {
                 if ((installFlags & PackageManager.INSTALL_DRY_RUN) != 0) {
                     String packageName = "";
                     try {
diff --git a/services/core/java/com/android/server/pm/PackageVerificationState.java b/services/core/java/com/android/server/pm/PackageVerificationState.java
index c50bf59..ea7af90 100644
--- a/services/core/java/com/android/server/pm/PackageVerificationState.java
+++ b/services/core/java/com/android/server/pm/PackageVerificationState.java
@@ -22,18 +22,17 @@
 import com.android.server.pm.PackageManagerService.InstallParams;
 
 /**
- * Tracks the package verification state for a particular package. Each package
- * verification has a required verifier and zero or more sufficient verifiers.
- * Only one of the sufficient verifier list must return affirmative to allow the
- * package to be considered verified. If there are zero sufficient verifiers,
- * then package verification is considered complete.
+ * Tracks the package verification state for a particular package. Each package verification has a
+ * required verifier and zero or more sufficient verifiers. Only one of the sufficient verifier list
+ * must return affirmative to allow the package to be considered verified. If there are zero
+ * sufficient verifiers, then package verification is considered complete.
  */
 class PackageVerificationState {
     private final InstallParams mParams;
 
     private final SparseBooleanArray mSufficientVerifierUids;
 
-    private final int mRequiredVerifierUid;
+    private int mRequiredVerifierUid;
 
     private boolean mSufficientVerificationComplete;
 
@@ -45,16 +44,13 @@
 
     private boolean mExtendedTimeout;
 
+    private boolean mIntegrityVerificationComplete;
+
     /**
-     * Create a new package verification state where {@code requiredVerifierUid}
-     * is the user ID for the package that must reply affirmative before things
-     * can continue.
-     *
-     * @param requiredVerifierUid user ID of required package verifier
-     * @param args
+     * Create a new package verification state where {@code requiredVerifierUid} is the user ID for
+     * the package that must reply affirmative before things can continue.
      */
-    PackageVerificationState(int requiredVerifierUid, InstallParams params) {
-        mRequiredVerifierUid = requiredVerifierUid;
+    PackageVerificationState(InstallParams params) {
         mParams = params;
         mSufficientVerifierUids = new SparseBooleanArray();
         mExtendedTimeout = false;
@@ -64,6 +60,11 @@
         return mParams;
     }
 
+    /** Sets the user ID of the required package verifier. */
+    void setRequiredVerifierUid(int uid) {
+        mRequiredVerifierUid = uid;
+    }
+
     /**
      * Add a verifier which is added to our sufficient list.
      *
@@ -74,8 +75,8 @@
     }
 
     /**
-     * Should be called when a verification is received from an agent so the
-     * state of the package verification can be tracked.
+     * Should be called when a verification is received from an agent so the state of the package
+     * verification can be tracked.
      *
      * @param uid user ID of the verifying agent
      * @return {@code true} if the verifying agent actually exists in our list
@@ -114,9 +115,8 @@
     }
 
     /**
-     * Returns whether verification is considered complete. This means that the
-     * required verifier and at least one of the sufficient verifiers has
-     * returned a positive verification.
+     * Returns whether verification is considered complete. This means that the required verifier
+     * and at least one of the sufficient verifiers has returned a positive verification.
      *
      * @return {@code true} when verification is considered complete
      */
@@ -133,8 +133,8 @@
     }
 
     /**
-     * Returns whether installation should be allowed. This should only be
-     * called after {@link #isVerificationComplete()} returns {@code true}.
+     * Returns whether installation should be allowed. This should only be called after {@link
+     * #isVerificationComplete()} returns {@code true}.
      *
      * @return {@code true} if installation should be allowed
      */
@@ -150,9 +150,7 @@
         return true;
     }
 
-    /**
-     * Extend the timeout for this Package to be verified.
-     */
+    /** Extend the timeout for this Package to be verified. */
     void extendTimeout() {
         if (!mExtendedTimeout) {
             mExtendedTimeout = true;
@@ -167,4 +165,16 @@
     boolean timeoutExtended() {
         return mExtendedTimeout;
     }
+
+    void setIntegrityVerificationResult(int code) {
+        mIntegrityVerificationComplete = true;
+    }
+
+    boolean isIntegrityVerificationComplete() {
+        return mIntegrityVerificationComplete;
+    }
+
+    boolean areAllVerificationsComplete() {
+        return mIntegrityVerificationComplete && isVerificationComplete();
+    }
 }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index fd95ac5..45c012e 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1881,7 +1881,10 @@
 
         if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED
                 || inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
-            if (insideParentBounds && mStack != null) {
+            if (insideParentBounds && WindowConfiguration.isFloating(windowingMode)) {
+                mTmpNonDecorBounds.set(mTmpFullBounds);
+                mTmpStableBounds.set(mTmpFullBounds);
+            } else if (insideParentBounds && mStack != null) {
                 final DisplayInfo di = new DisplayInfo();
                 mStack.getDisplay().mDisplay.getDisplayInfo(di);
 
diff --git a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
index 37ff06a..c080332 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
@@ -16,12 +16,6 @@
 
 package com.android.server.integrity;
 
-import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ID;
-
-import static org.mockito.Mockito.verify;
-
-import android.content.Intent;
-import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 
 import androidx.test.InstrumentationRegistry;
@@ -56,17 +50,7 @@
     }
 
     @Test
-    public void integrityVerification_allow() {
-        int verificationId = 2;
-        Intent integrityVerificationIntent = new Intent();
-        integrityVerificationIntent.setAction(Intent.ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
-        integrityVerificationIntent.putExtra(EXTRA_VERIFICATION_ID, verificationId);
-
-        // We cannot send the broadcast using the context since it is a protected broadcast and
-        // we will get a security exception.
-        mService.handleIntegrityVerification(integrityVerificationIntent);
-
-        verify(mPackageManagerInternal)
-                .setIntegrityVerificationResult(verificationId, PackageManager.VERIFICATION_ALLOW);
+    public void noop() {
+        // We need this test just as a place holder since an empty test suite is treated as error.
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java
index ad74901..0bb2d44 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java
@@ -44,48 +44,66 @@
 @RunWith(JUnit4.class)
 public class RuleXmlSerializerTest {
 
+    private static final String SAMPLE_INSTALLER_NAME = "com.test.installer";
+    private static final String SAMPLE_INSTALLER_CERT = "installer_cert";
+
     @Test
-    public void testXmlString_serializeEmptyRule() throws Exception {
-        Rule rule = null;
+    public void testXmlString_serializeEmptyRuleList() throws Exception {
         RuleSerializer xmlSerializer = new RuleXmlSerializer();
         String expectedRules = "<RL />";
 
         byte[] actualRules =
                 xmlSerializer.serialize(
-                        Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
+                        Collections.emptyList(), /* formatVersion= */ Optional.empty());
 
         assertEquals(expectedRules, new String(actualRules, StandardCharsets.UTF_8));
     }
 
     @Test
-    public void testXmlString_serializeMultipleRules_oneEmpty() throws Exception {
-        Rule rule1 = null;
-        Rule rule2 =
+    public void testXmlString_serializeMultipleRules_indexingOrderPreserved() throws Exception {
+        String packageNameA = "aaa";
+        String packageNameB = "bbb";
+        String packageNameC = "ccc";
+        String appCert1 = "cert1";
+        String appCert2 = "cert2";
+        String appCert3 = "cert3";
+        Rule installerRule =
                 new Rule(
-                        new AtomicFormula.StringAtomicFormula(
-                                AtomicFormula.PACKAGE_NAME,
-                                "com.app.test",
-                                /* isHashedValue= */ false),
+                        new CompoundFormula(
+                                CompoundFormula.AND,
+                                Arrays.asList(
+                                        new AtomicFormula.StringAtomicFormula(
+                                                AtomicFormula.INSTALLER_NAME,
+                                                SAMPLE_INSTALLER_NAME,
+                                                /* isHashedValue= */ false),
+                                        new AtomicFormula.StringAtomicFormula(
+                                                AtomicFormula.INSTALLER_CERTIFICATE,
+                                                SAMPLE_INSTALLER_CERT,
+                                                /* isHashedValue= */ false))),
                         Rule.DENY);
-        RuleSerializer xmlSerializer = new RuleXmlSerializer();
-        Map<String, String> packageNameAttrs = new LinkedHashMap<>();
-        packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
-        packageNameAttrs.put("V", "com.app.test");
-        packageNameAttrs.put("H", "false");
-        String expectedRules =
-                "<RL>"
-                        + generateTagWithAttribute(
-                                /* tag= */ "R",
-                                Collections.singletonMap("E", String.valueOf(Rule.DENY)),
-                                /* closed= */ false)
-                        + generateTagWithAttribute(
-                                /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
-                        + "</R>"
-                        + "</RL>";
 
+        RuleSerializer xmlSerializer = new RuleXmlSerializer();
         byte[] actualRules =
                 xmlSerializer.serialize(
-                        Arrays.asList(rule1, rule2), /* formatVersion= */ Optional.empty());
+                        Arrays.asList(
+                                installerRule,
+                                getRuleWithAppCertificateAndSampleInstallerName(appCert1),
+                                getRuleWithPackageNameAndSampleInstallerName(packageNameB),
+                                getRuleWithAppCertificateAndSampleInstallerName(appCert3),
+                                getRuleWithPackageNameAndSampleInstallerName(packageNameC),
+                                getRuleWithAppCertificateAndSampleInstallerName(appCert2),
+                                getRuleWithPackageNameAndSampleInstallerName(packageNameA)),
+                        /* formatVersion= */ Optional.empty());
+
+        String expectedRules = "<RL>"
+                + getSerializedCompoundRuleWithPackageNameAndSampleInstallerName(packageNameA)
+                + getSerializedCompoundRuleWithPackageNameAndSampleInstallerName(packageNameB)
+                + getSerializedCompoundRuleWithPackageNameAndSampleInstallerName(packageNameC)
+                + getSerializedCompoundRuleWithAppCertificateAndSampleInstallerName(appCert1)
+                + getSerializedCompoundRuleWithAppCertificateAndSampleInstallerName(appCert2)
+                + getSerializedCompoundRuleWithAppCertificateAndSampleInstallerName(appCert3)
+                + getSerializedCompoundRuleWithSampleInstallerNameAndCert()
+                + "</RL>";
 
         assertEquals(expectedRules, new String(actualRules, StandardCharsets.UTF_8));
     }
@@ -371,7 +389,7 @@
 
         assertExpectException(
                 RuleSerializeException.class,
-                /* expectedExceptionMessageRegex */ "Invalid formula type",
+                /* expectedExceptionMessageRegex */ "Malformed rule identified.",
                 () ->
                         xmlSerializer.serialize(
                                 Collections.singletonList(rule),
@@ -393,6 +411,124 @@
         return res.toString();
     }
 
+    private Rule getRuleWithPackageNameAndSampleInstallerName(String packageName) {
+        return new Rule(
+                new CompoundFormula(
+                        CompoundFormula.AND,
+                        Arrays.asList(
+                                new AtomicFormula.StringAtomicFormula(
+                                        AtomicFormula.PACKAGE_NAME,
+                                        packageName,
+                                        /* isHashedValue= */ false),
+                                new AtomicFormula.StringAtomicFormula(
+                                        AtomicFormula.INSTALLER_NAME,
+                                        SAMPLE_INSTALLER_NAME,
+                                        /* isHashedValue= */ false))),
+                Rule.DENY);
+    }
+
+    private String getSerializedCompoundRuleWithPackageNameAndSampleInstallerName(
+            String packageName) {
+
+        Map<String, String> packageNameAttrs = new LinkedHashMap<>();
+        packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+        packageNameAttrs.put("V", packageName);
+        packageNameAttrs.put("H", "false");
+
+        Map<String, String> installerNameAttrs = new LinkedHashMap<>();
+        installerNameAttrs.put("K", String.valueOf(AtomicFormula.INSTALLER_NAME));
+        installerNameAttrs.put("V", SAMPLE_INSTALLER_NAME);
+        installerNameAttrs.put("H", "false");
+
+        return generateTagWithAttribute(
+                        /* tag= */ "R",
+                        Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+                        /* closed= */ false)
+                + generateTagWithAttribute(
+                        /* tag= */ "OF",
+                        Collections.singletonMap("C", String.valueOf(CompoundFormula.AND)),
+                        /* closed= */ false)
+                + generateTagWithAttribute(
+                        /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+                + generateTagWithAttribute(
+                        /* tag= */ "AF", installerNameAttrs, /* closed= */ true)
+                + "</OF>"
+                + "</R>";
+    }
+
+
+    private Rule getRuleWithAppCertificateAndSampleInstallerName(String certificate) {
+        return new Rule(
+                new CompoundFormula(
+                        CompoundFormula.AND,
+                        Arrays.asList(
+                                new AtomicFormula.StringAtomicFormula(
+                                        AtomicFormula.APP_CERTIFICATE,
+                                        certificate,
+                                        /* isHashedValue= */ false),
+                                new AtomicFormula.StringAtomicFormula(
+                                        AtomicFormula.INSTALLER_NAME,
+                                        SAMPLE_INSTALLER_NAME,
+                                        /* isHashedValue= */ false))),
+                Rule.DENY);
+    }
+
+    private String getSerializedCompoundRuleWithAppCertificateAndSampleInstallerName(
+            String appCert) {
+
+        Map<String, String> packageNameAttrs = new LinkedHashMap<>();
+        packageNameAttrs.put("K", String.valueOf(AtomicFormula.APP_CERTIFICATE));
+        packageNameAttrs.put("V", appCert);
+        packageNameAttrs.put("H", "false");
+
+        Map<String, String> installerNameAttrs = new LinkedHashMap<>();
+        installerNameAttrs.put("K", String.valueOf(AtomicFormula.INSTALLER_NAME));
+        installerNameAttrs.put("V", SAMPLE_INSTALLER_NAME);
+        installerNameAttrs.put("H", "false");
+
+        return generateTagWithAttribute(
+                        /* tag= */ "R",
+                        Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+                        /* closed= */ false)
+                + generateTagWithAttribute(
+                        /* tag= */ "OF",
+                        Collections.singletonMap("C", String.valueOf(CompoundFormula.AND)),
+                        /* closed= */ false)
+                + generateTagWithAttribute(
+                        /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+                + generateTagWithAttribute(
+                        /* tag= */ "AF", installerNameAttrs, /* closed= */ true)
+                + "</OF>"
+                + "</R>";
+    }
+
+    private String getSerializedCompoundRuleWithSampleInstallerNameAndCert() {
+        Map<String, String> installerNameAttrs = new LinkedHashMap<>();
+        installerNameAttrs.put("K", String.valueOf(AtomicFormula.INSTALLER_NAME));
+        installerNameAttrs.put("V", SAMPLE_INSTALLER_NAME);
+        installerNameAttrs.put("H", "false");
+
+        Map<String, String> installerCertAttrs = new LinkedHashMap<>();
+        installerCertAttrs.put("K", String.valueOf(AtomicFormula.INSTALLER_CERTIFICATE));
+        installerCertAttrs.put("V", SAMPLE_INSTALLER_CERT);
+        installerCertAttrs.put("H", "false");
+
+        return generateTagWithAttribute(
+                        /* tag= */ "R",
+                        Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+                        /* closed= */ false)
+                + generateTagWithAttribute(
+                        /* tag= */ "OF",
+                        Collections.singletonMap("C", String.valueOf(CompoundFormula.AND)),
+                        /* closed= */ false)
+                + generateTagWithAttribute(
+                        /* tag= */ "AF", installerNameAttrs, /* closed= */ true)
+                + generateTagWithAttribute(
+                        /* tag= */ "AF", installerCertAttrs, /* closed= */ true)
+                + "</OF>"
+                + "</R>";
+    }
+
     private Formula getInvalidFormula() {
         return new Formula() {
             @Override
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageVerificationStateTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageVerificationStateTest.java
index ebd3633..1fff4f0 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageVerificationStateTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageVerificationStateTest.java
@@ -17,8 +17,7 @@
 package com.android.server.pm;
 
 import android.content.pm.PackageManager;
-import com.android.server.pm.PackageVerificationState;
-
+import android.content.pm.PackageManagerInternal;
 import android.test.AndroidTestCase;
 
 public class PackageVerificationStateTest extends AndroidTestCase {
@@ -29,7 +28,8 @@
     private static final int SUFFICIENT_UID_2 = 8938;
 
     public void testPackageVerificationState_OnlyRequiredVerifier_AllowedInstall() {
-        PackageVerificationState state = new PackageVerificationState(REQUIRED_UID, null);
+        PackageVerificationState state = new PackageVerificationState(null);
+        state.setRequiredVerifierUid(REQUIRED_UID);
 
         assertFalse("Verification should not be marked as complete yet",
                 state.isVerificationComplete());
@@ -44,7 +44,8 @@
     }
 
     public void testPackageVerificationState_OnlyRequiredVerifier_DeniedInstall() {
-        PackageVerificationState state = new PackageVerificationState(REQUIRED_UID, null);
+        PackageVerificationState state = new PackageVerificationState(null);
+        state.setRequiredVerifierUid(REQUIRED_UID);
 
         assertFalse("Verification should not be marked as complete yet",
                 state.isVerificationComplete());
@@ -59,7 +60,8 @@
     }
 
     public void testPackageVerificationState_RequiredAndOneSufficient_RequiredDeniedInstall() {
-        PackageVerificationState state = new PackageVerificationState(REQUIRED_UID, null);
+        PackageVerificationState state = new PackageVerificationState(null);
+        state.setRequiredVerifierUid(REQUIRED_UID);
 
         assertFalse("Verification should not be marked as complete yet",
                 state.isVerificationComplete());
@@ -84,7 +86,8 @@
     }
 
     public void testPackageVerificationState_RequiredAndOneSufficient_SufficientDeniedInstall() {
-        PackageVerificationState state = new PackageVerificationState(REQUIRED_UID, null);
+        PackageVerificationState state = new PackageVerificationState(null);
+        state.setRequiredVerifierUid(REQUIRED_UID);
 
         assertFalse("Verification should not be marked as complete yet",
                 state.isVerificationComplete());
@@ -109,7 +112,8 @@
     }
 
     public void testPackageVerificationState_RequiredAndTwoSufficient_OneSufficientIsEnough() {
-        PackageVerificationState state = new PackageVerificationState(REQUIRED_UID, null);
+        PackageVerificationState state = new PackageVerificationState(null);
+        state.setRequiredVerifierUid(REQUIRED_UID);
 
         assertFalse("Verification should not be marked as complete yet",
                 state.isVerificationComplete());
@@ -135,7 +139,8 @@
     }
 
     public void testPackageVerificationState_RequiredAndTwoSufficient_SecondSufficientIsEnough() {
-        PackageVerificationState state = new PackageVerificationState(REQUIRED_UID, null);
+        PackageVerificationState state = new PackageVerificationState(null);
+        state.setRequiredVerifierUid(REQUIRED_UID);
 
         assertFalse("Verification should not be marked as complete yet",
                 state.isVerificationComplete());
@@ -166,7 +171,8 @@
     }
 
     public void testPackageVerificationState_RequiredAndTwoSufficient_RequiredOverrides() {
-        PackageVerificationState state = new PackageVerificationState(REQUIRED_UID, null);
+        PackageVerificationState state = new PackageVerificationState(null);
+        state.setRequiredVerifierUid(REQUIRED_UID);
 
         assertFalse("Verification should not be marked as complete yet",
                 state.isVerificationComplete());
@@ -202,4 +208,55 @@
         assertTrue("Installation should be marked as allowed still",
                 state.isInstallAllowed());
     }
+
+    public void testAreAllVerificationsComplete_onlyVerificationPasses() {
+        PackageVerificationState state = new PackageVerificationState(null);
+        state.setRequiredVerifierUid(REQUIRED_UID);
+        assertFalse(state.areAllVerificationsComplete());
+
+        state.setVerifierResponse(REQUIRED_UID, PackageManager.VERIFICATION_ALLOW);
+
+        assertFalse(state.areAllVerificationsComplete());
+    }
+
+    public void testAreAllVerificationsComplete_onlyIntegrityCheckPasses() {
+        PackageVerificationState state = new PackageVerificationState(null);
+        state.setRequiredVerifierUid(REQUIRED_UID);
+        assertFalse(state.areAllVerificationsComplete());
+
+        state.setIntegrityVerificationResult(PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
+
+        assertFalse(state.areAllVerificationsComplete());
+    }
+
+    public void testAreAllVerificationsComplete_bothPasses() {
+        PackageVerificationState state = new PackageVerificationState(null);
+        state.setRequiredVerifierUid(REQUIRED_UID);
+        assertFalse(state.areAllVerificationsComplete());
+
+        state.setIntegrityVerificationResult(PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
+        state.setVerifierResponse(REQUIRED_UID, PackageManager.VERIFICATION_ALLOW);
+
+        assertTrue(state.areAllVerificationsComplete());
+    }
+
+    public void testAreAllVerificationsComplete_onlyVerificationFails() {
+        PackageVerificationState state = new PackageVerificationState(null);
+        state.setRequiredVerifierUid(REQUIRED_UID);
+        assertFalse(state.areAllVerificationsComplete());
+
+        state.setVerifierResponse(REQUIRED_UID, PackageManager.VERIFICATION_REJECT);
+
+        assertFalse(state.areAllVerificationsComplete());
+    }
+
+    public void testAreAllVerificationsComplete_onlyIntegrityCheckFails() {
+        PackageVerificationState state = new PackageVerificationState(null);
+        state.setRequiredVerifierUid(REQUIRED_UID);
+        assertFalse(state.areAllVerificationsComplete());
+
+        state.setIntegrityVerificationResult(PackageManagerInternal.INTEGRITY_VERIFICATION_REJECT);
+
+        assertFalse(state.areAllVerificationsComplete());
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index 1a18df5..de6d752 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -427,6 +427,61 @@
         assertNotEquals(origScreenH, task.getConfiguration().screenHeightDp);
     }
 
+    @Test
+    public void testInsetDisregardedWhenFreeformOverlapsNavBar() {
+        DisplayContent display = mService.mRootActivityContainer.getDefaultDisplay();
+        ActivityStack stack = display.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        DisplayInfo displayInfo = new DisplayInfo();
+        mService.mContext.getDisplay().getDisplayInfo(displayInfo);
+        final int displayHeight = displayInfo.logicalHeight;
+        final Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
+        final Configuration inOutConfig = new Configuration();
+        final Configuration parentConfig = new Configuration();
+        final int longSide = 1200;
+        final int shortSide = 600;
+        parentConfig.densityDpi = 400;
+        parentConfig.screenHeightDp = 200; // 200 * 400 / 160 = 500px
+        parentConfig.screenWidthDp = 100; // 100 * 400 / 160 = 250px
+        parentConfig.windowConfiguration.setRotation(ROTATION_0);
+
+        final float density = 2.5f; // densityDpi / DENSITY_DEFAULT_SCALE = 400 / 160.0f
+        final int longSideDp = 480; // longSide / density = 1200 / 400 * 160
+        final int shortSideDp = 240; // shortSide / density = 600 / 400 * 160
+        final int screenLayout = parentConfig.screenLayout
+                & (Configuration.SCREENLAYOUT_LONG_MASK | Configuration.SCREENLAYOUT_SIZE_MASK);
+        final int reducedScreenLayout =
+                Configuration.reduceScreenLayout(screenLayout, longSideDp, shortSideDp);
+
+        // Portrait bounds overlapping with navigation bar, without insets.
+        inOutConfig.windowConfiguration.getBounds().set(0,
+                displayHeight - 10 - longSide,
+                shortSide,
+                displayHeight - 10);
+        // Set to freeform mode to verify bug fix.
+        inOutConfig.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+
+        task.computeConfigResourceOverrides(inOutConfig, parentConfig);
+
+        assertEquals(parentConfig.screenWidthDp, inOutConfig.screenWidthDp);
+        assertEquals(parentConfig.screenHeightDp, inOutConfig.screenHeightDp);
+        assertEquals(reducedScreenLayout, inOutConfig.screenLayout);
+
+        inOutConfig.setToDefaults();
+        // Landscape bounds overlapping with navigtion bar, without insets.
+        inOutConfig.windowConfiguration.getBounds().set(0,
+                displayHeight - 10 - shortSide,
+                longSide,
+                displayHeight - 10);
+        inOutConfig.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+
+        task.computeConfigResourceOverrides(inOutConfig, parentConfig);
+
+        assertEquals(parentConfig.screenWidthDp, inOutConfig.screenWidthDp);
+        assertEquals(parentConfig.screenHeightDp, inOutConfig.screenHeightDp);
+        assertEquals(reducedScreenLayout, inOutConfig.screenLayout);
+    }
+
     /** Ensures that the alias intent won't have target component resolved. */
     @Test
     public void testTaskIntentActivityAlias() {
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index 3940a3b..9b9997f 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -485,6 +485,86 @@
             PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING})
     public @interface PreciseCallStates {}
 
+    @IntDef(value = {
+            DisconnectCause.NOT_VALID,
+            DisconnectCause.NOT_DISCONNECTED,
+            DisconnectCause.INCOMING_MISSED,
+            DisconnectCause.NORMAL,
+            DisconnectCause.LOCAL,
+            DisconnectCause.BUSY,
+            DisconnectCause.CONGESTION,
+            DisconnectCause.MMI,
+            DisconnectCause.INVALID_NUMBER,
+            DisconnectCause.NUMBER_UNREACHABLE,
+            DisconnectCause.SERVER_UNREACHABLE,
+            DisconnectCause.INVALID_CREDENTIALS,
+            DisconnectCause.OUT_OF_NETWORK,
+            DisconnectCause.SERVER_ERROR,
+            DisconnectCause.TIMED_OUT,
+            DisconnectCause.LOST_SIGNAL,
+            DisconnectCause.LIMIT_EXCEEDED,
+            DisconnectCause.INCOMING_REJECTED,
+            DisconnectCause.POWER_OFF,
+            DisconnectCause.OUT_OF_SERVICE,
+            DisconnectCause.ICC_ERROR,
+            DisconnectCause.CALL_BARRED,
+            DisconnectCause.FDN_BLOCKED,
+            DisconnectCause.CS_RESTRICTED,
+            DisconnectCause.CS_RESTRICTED_NORMAL,
+            DisconnectCause.CS_RESTRICTED_EMERGENCY,
+            DisconnectCause.UNOBTAINABLE_NUMBER,
+            DisconnectCause.CDMA_LOCKED_UNTIL_POWER_CYCLE,
+            DisconnectCause.CDMA_DROP,
+            DisconnectCause.CDMA_INTERCEPT,
+            DisconnectCause.CDMA_REORDER,
+            DisconnectCause.CDMA_SO_REJECT,
+            DisconnectCause.CDMA_RETRY_ORDER,
+            DisconnectCause.CDMA_ACCESS_FAILURE,
+            DisconnectCause.CDMA_PREEMPTED,
+            DisconnectCause.CDMA_NOT_EMERGENCY,
+            DisconnectCause.CDMA_ACCESS_BLOCKED,
+            DisconnectCause.ERROR_UNSPECIFIED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DisconnectCauses {
+    }
+
+    @IntDef(value = {
+            PreciseDisconnectCause.NOT_VALID,
+            PreciseDisconnectCause.NO_DISCONNECT_CAUSE_AVAILABLE,
+            PreciseDisconnectCause.UNOBTAINABLE_NUMBER,
+            PreciseDisconnectCause.NORMAL,
+            PreciseDisconnectCause.BUSY,
+            PreciseDisconnectCause.NUMBER_CHANGED,
+            PreciseDisconnectCause.STATUS_ENQUIRY,
+            PreciseDisconnectCause.NORMAL_UNSPECIFIED,
+            PreciseDisconnectCause.NO_CIRCUIT_AVAIL,
+            PreciseDisconnectCause.TEMPORARY_FAILURE,
+            PreciseDisconnectCause.SWITCHING_CONGESTION,
+            PreciseDisconnectCause.CHANNEL_NOT_AVAIL,
+            PreciseDisconnectCause.QOS_NOT_AVAIL,
+            PreciseDisconnectCause.BEARER_NOT_AVAIL,
+            PreciseDisconnectCause.ACM_LIMIT_EXCEEDED,
+            PreciseDisconnectCause.CALL_BARRED,
+            PreciseDisconnectCause.FDN_BLOCKED,
+            PreciseDisconnectCause.IMSI_UNKNOWN_IN_VLR,
+            PreciseDisconnectCause.IMEI_NOT_ACCEPTED,
+            PreciseDisconnectCause.CDMA_LOCKED_UNTIL_POWER_CYCLE,
+            PreciseDisconnectCause.CDMA_DROP,
+            PreciseDisconnectCause.CDMA_INTERCEPT,
+            PreciseDisconnectCause.CDMA_REORDER,
+            PreciseDisconnectCause.CDMA_SO_REJECT,
+            PreciseDisconnectCause.CDMA_RETRY_ORDER,
+            PreciseDisconnectCause.CDMA_ACCESS_FAILURE,
+            PreciseDisconnectCause.CDMA_PREEMPTED,
+            PreciseDisconnectCause.CDMA_NOT_EMERGENCY,
+            PreciseDisconnectCause.CDMA_ACCESS_BLOCKED,
+            PreciseDisconnectCause.ERROR_UNSPECIFIED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PreciseDisconnectCauses {
+    }
+
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"RIL_RADIO_TECHNOLOGY_" }, value = {
             ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN,
diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java
index b7dab16..e523fba 100644
--- a/telephony/java/android/telephony/CellIdentity.java
+++ b/telephony/java/android/telephony/CellIdentity.java
@@ -19,6 +19,7 @@
 import android.annotation.CallSuper;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
@@ -181,7 +182,8 @@
      * @return a CellLocation object for this CellIdentity
      * @hide
      */
-    public abstract CellLocation asCellLocation();
+    @SystemApi
+    public abstract @NonNull CellLocation asCellLocation();
 
     @Override
     public boolean equals(Object other) {
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index 880d3db..54236b42 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -16,6 +16,7 @@
 
 package android.telephony;
 
+import android.annotation.NonNull;
 import android.os.Parcel;
 import android.telephony.cdma.CdmaCellLocation;
 
@@ -198,6 +199,7 @@
     }
 
     /** @hide */
+    @NonNull
     @Override
     public CdmaCellLocation asCellLocation() {
         CdmaCellLocation cl = new CdmaCellLocation();
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index 25c6577..4e4454d 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -16,6 +16,7 @@
 
 package android.telephony;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
@@ -200,6 +201,7 @@
     }
 
     /** @hide */
+    @NonNull
     @Override
     public GsmCellLocation asCellLocation() {
         GsmCellLocation cl = new GsmCellLocation();
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index 997b19f..c3fc73b 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -16,6 +16,7 @@
 
 package android.telephony;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Build;
@@ -232,6 +233,7 @@
      *
      * @hide
      */
+    @NonNull
     @Override
     public GsmCellLocation asCellLocation() {
         GsmCellLocation cl = new GsmCellLocation();
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index edc838c..e3fec7b 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -17,6 +17,7 @@
 package android.telephony;
 
 import android.annotation.IntRange;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.Parcel;
 import android.telephony.gsm.GsmCellLocation;
@@ -77,6 +78,7 @@
      * @return a CellLocation object for this CellIdentity.
      * @hide
      */
+    @NonNull
     @Override
     public CellLocation asCellLocation() {
         return new GsmCellLocation();
diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java
index 558e346..8f812b6 100644
--- a/telephony/java/android/telephony/CellIdentityTdscdma.java
+++ b/telephony/java/android/telephony/CellIdentityTdscdma.java
@@ -171,6 +171,7 @@
     }
 
     /** @hide */
+    @NonNull
     @Override
     public GsmCellLocation asCellLocation() {
         GsmCellLocation cl = new GsmCellLocation();
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index 031fed1..556bc32 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -16,6 +16,7 @@
 
 package android.telephony;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
@@ -196,6 +197,7 @@
     }
 
     /** @hide */
+    @NonNull
     @Override
     public GsmCellLocation asCellLocation() {
         GsmCellLocation cl = new GsmCellLocation();
diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java
index 9f75332..bfa6326 100644
--- a/telephony/java/android/telephony/PreciseCallState.java
+++ b/telephony/java/android/telephony/PreciseCallState.java
@@ -16,19 +16,18 @@
 
 package android.telephony;
 
-import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.telephony.Annotation.DisconnectCauses;
 import android.telephony.Annotation.PreciseCallStates;
+import android.telephony.Annotation.PreciseDisconnectCauses;
 import android.telephony.DisconnectCause;
 import android.telephony.PreciseDisconnectCause;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
 
 /**
@@ -73,19 +72,26 @@
     private @PreciseCallStates int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID;
     private @PreciseCallStates int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID;
     private @PreciseCallStates int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID;
-    private int mDisconnectCause = DisconnectCause.NOT_VALID;
-    private int mPreciseDisconnectCause = PreciseDisconnectCause.NOT_VALID;
+    private @DisconnectCauses int mDisconnectCause = DisconnectCause.NOT_VALID;
+    private @PreciseDisconnectCauses int mPreciseDisconnectCause = PreciseDisconnectCause.NOT_VALID;
 
     /**
-     * Constructor
+     * Construct PreciseCallState with parameters
+     *
+     * @param ringingCall ring call state
+     * @param foregroundCall foreground call state
+     * @param backgroundCall background call state
+     * @param disconnectCause disconnect cause
+     * @param preciseDisconnectCause precise disconnect cause
      *
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
     public PreciseCallState(@PreciseCallStates int ringingCall,
                             @PreciseCallStates int foregroundCall,
-                            @PreciseCallStates int backgroundCall, int disconnectCause,
-                            int preciseDisconnectCause) {
+                            @PreciseCallStates int backgroundCall,
+                            @DisconnectCauses int disconnectCause,
+                            @PreciseDisconnectCauses int preciseDisconnectCause) {
         mRingingCallState = ringingCall;
         mForegroundCallState = foregroundCall;
         mBackgroundCallState = backgroundCall;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 60fda09..a96325e 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1950,14 +1950,9 @@
                 return null;
             }
 
-            Bundle bundle = telephony.getCellLocation(mContext.getOpPackageName(),
+            CellIdentity cellIdentity = telephony.getCellLocation(mContext.getOpPackageName(),
                     mContext.getFeatureId());
-            if (bundle == null || bundle.isEmpty()) {
-                Rlog.d(TAG, "getCellLocation returning null because CellLocation is unavailable");
-                return null;
-            }
-
-            CellLocation cl = CellLocation.newFromBundle(bundle);
+            CellLocation cl = cellIdentity.asCellLocation();
             if (cl == null || cl.isEmpty()) {
                 Rlog.d(TAG, "getCellLocation returning null because CellLocation is empty or"
                         + " phone type doesn't match CellLocation type");
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 97b24ae..0baac71 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -30,6 +30,7 @@
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telephony.CarrierRestrictionRules;
+import android.telephony.CellIdentity;
 import android.telephony.CellInfo;
 import android.telephony.ClientRequestStats;
 import android.telephony.IccOpenLogicalChannelResponse;
@@ -305,7 +306,8 @@
      */
     boolean isDataConnectivityPossible(int subId);
 
-    Bundle getCellLocation(String callingPkg, String callingFeatureId);
+    // Uses CellIdentity which is Parcelable here; will convert to CellLocation in client.
+    CellIdentity getCellLocation(String callingPkg, String callingFeatureId);
 
     /**
      * Returns the ISO country code equivalent of the current registered