Merge "Catch Activity Not Found Exception when switching to specific TV input."
diff --git a/api/current.txt b/api/current.txt
index ff93504..0652fdd 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -12388,7 +12388,7 @@
     method public String getPositionDescription();
     method @AnyRes public int getResourceId(@StyleableRes int, int);
     method public android.content.res.Resources getResources();
-    method @StyleRes public int getSourceStyleResourceId(@StyleableRes int, @StyleRes int);
+    method @StyleRes public int getSourceResourceId(@StyleableRes int, @StyleRes int);
     method @Nullable public String getString(@StyleableRes int);
     method public CharSequence getText(@StyleableRes int);
     method public CharSequence[] getTextArray(@StyleableRes int);
@@ -43848,12 +43848,12 @@
 
   public class TelecomManager {
     method public void acceptHandover(android.net.Uri, int, android.telecom.PhoneAccountHandle);
-    method @RequiresPermission(anyOf={android.Manifest.permission.ANSWER_PHONE_CALLS, android.Manifest.permission.MODIFY_PHONE_STATE}) public void acceptRingingCall();
-    method @RequiresPermission(anyOf={android.Manifest.permission.ANSWER_PHONE_CALLS, android.Manifest.permission.MODIFY_PHONE_STATE}) public void acceptRingingCall(int);
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ANSWER_PHONE_CALLS, android.Manifest.permission.MODIFY_PHONE_STATE}) public void acceptRingingCall();
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ANSWER_PHONE_CALLS, android.Manifest.permission.MODIFY_PHONE_STATE}) public void acceptRingingCall(int);
     method public void addNewIncomingCall(android.telecom.PhoneAccountHandle, android.os.Bundle);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void cancelMissedCallsNotification();
     method public android.content.Intent createManageBlockedNumbersIntent();
-    method @RequiresPermission(android.Manifest.permission.ANSWER_PHONE_CALLS) public boolean endCall();
+    method @Deprecated @RequiresPermission(android.Manifest.permission.ANSWER_PHONE_CALLS) public boolean endCall();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.net.Uri getAdnUriForPhoneAccount(android.telecom.PhoneAccountHandle);
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<android.telecom.PhoneAccountHandle> getCallCapablePhoneAccounts();
     method public String getDefaultDialerPackage();
@@ -48449,6 +48449,7 @@
     method public static boolean logEvent(int);
     method public static boolean logStart(int);
     method public static boolean logStop(int);
+    method public static void write(int, @NonNull java.lang.Object...);
   }
 
   public class StringBuilderPrinter implements android.util.Printer {
@@ -48534,7 +48535,7 @@
     field public int data;
     field public int density;
     field @AnyRes public int resourceId;
-    field public int sourceStyleResourceId;
+    field public int sourceResourceId;
     field public CharSequence string;
     field public int type;
   }
diff --git a/api/system-current.txt b/api/system-current.txt
index 8714c0f..8d98bc1 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9208,6 +9208,21 @@
     method public int getUid();
   }
 
+  public class StatsLogAtoms {
+    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED = 170; // 0xaa
+    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED = 8; // 0x8
+    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED = 5; // 0x5
+    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED = 1; // 0x1
+    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED = 3; // 0x3
+    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED = 2; // 0x2
+    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED = 6; // 0x6
+    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE = 7; // 0x7
+    field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED = 4; // 0x4
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef(prefix="PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__", value={android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED}) public static @interface StatsLogAtoms.PermissionGrantRequestResultReported_Result {
+  }
+
 }
 
 package android.view {
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 9a6387a..751b3e4 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -236,6 +236,7 @@
         BluetoothSmpPairingEventReported bluetooth_smp_pairing_event_reported = 167;
         ScreenTimeoutExtensionReported screen_timeout_extension_reported = 168;
         ProcessStartTime process_start_time = 169;
+        PermissionGrantRequestResultReported permission_grant_request_result_reported = 170;
     }
 
     // Pulled events will start at field 10000.
@@ -5097,6 +5098,48 @@
 }
 
 /**
+ * Information about a permission grant request
+ */
+message PermissionGrantRequestResultReported {
+    // unique value identifying an API call. A API call might result in multiple of these atoms
+    optional int64 request_id = 1;
+
+    // UID of package requesting the permission grant
+    optional int32 requesting_uid = 2 [(is_uid) = true];
+
+    // Name of package requesting the permission grant
+    optional string requesting_package_name = 3;
+
+    // The permission to be granted
+    optional string permission_name = 4;
+
+    // If the permission was explicitly requested via the API or added by the system
+    optional bool is_implicit = 5;
+
+    enum Result {
+        UNDEFINED = 0;
+        // permission request was ignored
+        IGNORED = 1;
+        // permission request was ignored because it was user fixed
+        IGNORED_USER_FIXED = 2;
+        // permission request was ignored because it was policy fixed
+        IGNORED_POLICY_FIXED = 3;
+        // permission was granted by user action
+        USER_GRANTED = 4;
+        // permission was automatically granted
+        AUTO_GRANTED = 5;
+        // permission was denied by user action
+        USER_DENIED = 6;
+        // permission was denied with prejudice by the user
+        USER_DENIED_WITH_PREJUDICE = 7;
+        // permission was automatically denied
+        AUTO_DENIED = 8;
+    }
+    // The result of the permission grant
+    optional Result result = 6;
+}
+
+/**
  * Logs when Omapi API used
  * Logged from:
  *     packages/apps/SecureElement/src/com/android/se/Terminal.java
diff --git a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java
index d9aba61..fc7b778 100644
--- a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java
+++ b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java
@@ -32,7 +32,8 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.logging.Level;
@@ -60,6 +61,7 @@
     };
     private static final Logger LOGGER = Logger.getLogger(TestDrive.class.getName());
 
+    private String mAdditionalAllowedPackage;
     private final Set<Long> mTrackedMetrics = new HashSet<>();
 
     public static void main(String[] args) {
@@ -69,11 +71,16 @@
         String remoteConfigPath = null;
 
         if (args.length < 1) {
-            LOGGER.log(Level.SEVERE, "Usage: ./test_drive <atomId1> <atomId2> ... <atomIdN>");
+            LOGGER.log(Level.SEVERE, "Usage: ./test_drive [-p additional_allowed_package] "
+                    + "<atomId1> <atomId2> ... <atomIdN>");
             return;
         }
 
-        for (int i = 0; i < args.length; i++) {
+        if (args.length >= 3 && args[0].equals("-p")) {
+            testDrive.mAdditionalAllowedPackage = args[1];
+        }
+
+        for (int i = testDrive.mAdditionalAllowedPackage == null ? 0 : 2; i < args.length; i++) {
             try {
                 int atomId = Integer.valueOf(args[i]);
                 if (Atom.getDescriptor().findFieldByNumber(atomId) == null) {
@@ -137,9 +144,15 @@
         long metricId = METRIC_ID_BASE;
         long atomMatcherId = ATOM_MATCHER_ID_BASE;
 
+        ArrayList<String> allowedSources = new ArrayList<>();
+        Collections.addAll(allowedSources, ALLOWED_LOG_SOURCES);
+        if (mAdditionalAllowedPackage != null) {
+            allowedSources.add(mAdditionalAllowedPackage);
+        }
+
         StatsdConfig.Builder builder = StatsdConfig.newBuilder();
         builder
-            .addAllAllowedLogSource(Arrays.asList(ALLOWED_LOG_SOURCES))
+            .addAllAllowedLogSource(allowedSources)
             .setHashStringsInMetricReport(false);
 
         for (int atomId : atomIds) {
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index d53834c..d36e076 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -72,7 +72,7 @@
     static final int STYLE_RESOURCE_ID = 3;
     static final int STYLE_CHANGING_CONFIGURATIONS = 4;
     static final int STYLE_DENSITY = 5;
-    static final int SYTLE_SOURCE_STYLE_RESOURCE_ID = 6;
+    static final int SYTLE_SOURCE_RESOURCE_ID = 6;
 
     @UnsupportedAppUsage
     private final Resources mResources;
@@ -1101,28 +1101,51 @@
     }
 
     /**
-     * Returns the resource ID of the style against which the specified attribute was resolved,
-     * otherwise returns defValue.
+     * Returns the resource ID of the style or layout against which the specified attribute was
+     * resolved, otherwise returns defValue.
+     *
+     * For example, if you we resolving two attributes {@code android:attribute1} and
+     * {@code android:attribute2} and you were inflating a {@link android.view.View} from
+     * {@code layout/my_layout.xml}:
+     * <pre>
+     *     &lt;View
+     *         style="@style/viewStyle"
+     *         android:layout_width="wrap_content"
+     *         android:layout_height="wrap_content"
+     *         android:attribute1="foo"/&gt;
+     * </pre>
+     *
+     * and {@code @style/viewStyle} is:
+     * <pre>
+     *     &lt;style android:name="viewStyle"&gt;
+     *         &lt;item name="android:attribute2"&gt;bar&lt;item/&gt;
+     *     &lt;style/&gt;
+     * </pre>
+     *
+     * then resolved {@link TypedArray} will have values that return source resource ID of
+     * {@code R.layout.my_layout} for {@code android:attribute1} and {@code R.style.viewStyle} for
+     * {@code android:attribute2}.
      *
      * @param index Index of attribute whose source style to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
+     * @param defaultValue Value to return if the attribute is not defined or
+     *                     not a resource.
      *
-     * @return Attribute source style resource ID or defValue if it was not resolved in any style.
+     * @return Either a style resource ID, layout resource ID, or defaultValue if it was not
+     * resolved in a style or layout.
      * @throws RuntimeException if the TypedArray has already been recycled.
      */
     @StyleRes
-    public int getSourceStyleResourceId(@StyleableRes int index, @StyleRes int defValue) {
+    public int getSourceResourceId(@StyleableRes int index, @StyleRes int defaultValue) {
         if (mRecycled) {
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
         index *= STYLE_NUM_ENTRIES;
-        final int resid = mData[index + SYTLE_SOURCE_STYLE_RESOURCE_ID];
+        final int resid = mData[index + SYTLE_SOURCE_RESOURCE_ID];
         if (resid != 0) {
             return resid;
         }
-        return defValue;
+        return defaultValue;
     }
 
     /**
@@ -1337,7 +1360,7 @@
                 data[index + STYLE_CHANGING_CONFIGURATIONS]);
         outValue.density = data[index + STYLE_DENSITY];
         outValue.string = (type == TypedValue.TYPE_STRING) ? loadStringValueAt(index) : null;
-        outValue.sourceStyleResourceId = data[index + SYTLE_SOURCE_STYLE_RESOURCE_ID];
+        outValue.sourceResourceId = data[index + SYTLE_SOURCE_RESOURCE_ID];
         return true;
     }
 
diff --git a/core/java/android/content/res/XmlBlock.java b/core/java/android/content/res/XmlBlock.java
index d8c3dde..626bf77 100644
--- a/core/java/android/content/res/XmlBlock.java
+++ b/core/java/android/content/res/XmlBlock.java
@@ -82,23 +82,22 @@
     public XmlResourceParser newParser(@AnyRes int resId) {
         synchronized (this) {
             if (mNative != 0) {
-                return new Parser(nativeCreateParseState(mNative), this, resId);
+                return new Parser(nativeCreateParseState(mNative, resId), this);
             }
             return null;
         }
     }
 
     /*package*/ final class Parser implements XmlResourceParser {
-        Parser(long parseState, XmlBlock block, @AnyRes int sourceResId) {
+        Parser(long parseState, XmlBlock block) {
             mParseState = parseState;
             mBlock = block;
             block.mOpenCount++;
-            mSourceResId = sourceResId;
         }
 
         @AnyRes
         public int getSourceResId() {
-            return mSourceResId;
+            return nativeGetSourceResId(mParseState);
         }
 
         public void setFeature(String name, boolean state) throws XmlPullParserException {
@@ -486,7 +485,6 @@
         private boolean mDecNextDepth = false;
         private int mDepth = 0;
         private int mEventType = START_DOCUMENT;
-        private @AnyRes int mSourceResId;
     }
 
     protected void finalize() throws Throwable {
@@ -515,7 +513,7 @@
                                                  int offset,
                                                  int size);
     private static final native long nativeGetStringBlock(long obj);
-    private static final native long nativeCreateParseState(long obj);
+    private static final native long nativeCreateParseState(long obj, int resId);
     private static final native void nativeDestroyParseState(long state);
     private static final native void nativeDestroy(long obj);
 
@@ -553,4 +551,6 @@
     private static final native int nativeGetStyleAttribute(long state);
     @FastNative
     private static final native int nativeGetAttributeIndex(long state, String namespace, String name);
+    @FastNative
+    private static final native int nativeGetSourceResId(long state);
 }
diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java
index 850d020..c59e573 100644
--- a/core/java/android/permission/PermissionControllerManager.java
+++ b/core/java/android/permission/PermissionControllerManager.java
@@ -269,6 +269,7 @@
     public void getRuntimePermissionBackup(@NonNull UserHandle user,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull OnGetRuntimePermissionBackupCallback callback) {
+        checkNotNull(user);
         checkNotNull(executor);
         checkNotNull(callback);
 
diff --git a/core/java/android/permission/PermissionControllerService.java b/core/java/android/permission/PermissionControllerService.java
index 70404c3..482f4a8 100644
--- a/core/java/android/permission/PermissionControllerService.java
+++ b/core/java/android/permission/PermissionControllerService.java
@@ -56,7 +56,7 @@
 /**
  * This service is meant to be implemented by the app controlling permissions.
  *
- * @see PermissionController
+ * @see PermissionControllerManager
  *
  * @hide
  */
@@ -98,10 +98,10 @@
      * Create a backup of the runtime permissions.
      *
      * @param user The user to back up
-     * @param out The stream to write the backup to
+     * @param backup The stream to write the backup to
      */
     public abstract void onGetRuntimePermissionsBackup(@NonNull UserHandle user,
-            @NonNull OutputStream out);
+            @NonNull OutputStream backup);
 
     /**
      * Gets the runtime permissions for an app.
@@ -297,11 +297,11 @@
     }
 
     private void getRuntimePermissionsBackup(@NonNull UserHandle user,
-            @NonNull ParcelFileDescriptor outFile) {
-        try (OutputStream out = new ParcelFileDescriptor.AutoCloseOutputStream(outFile)) {
-            onGetRuntimePermissionsBackup(user, out);
+            @NonNull ParcelFileDescriptor backupFile) {
+        try (OutputStream backup = new ParcelFileDescriptor.AutoCloseOutputStream(backupFile)) {
+            onGetRuntimePermissionsBackup(user, backup);
         } catch (IOException e) {
-            Log.e(LOG_TAG, "Could not open pipe to write backup tp", e);
+            Log.e(LOG_TAG, "Could not open pipe to write backup to", e);
         }
     }
 
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index bec654a..bff118e 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -958,13 +958,15 @@
         if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_MESSAGES,
                 isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_MESSAGES, defaultPolicy))) {
             priorityCategories |= Policy.PRIORITY_CATEGORY_MESSAGES;
-            messageSenders = getNotificationPolicySenders(zenPolicy.getPriorityMessageSenders());
+            messageSenders = getNotificationPolicySenders(zenPolicy.getPriorityMessageSenders(),
+                    messageSenders);
         }
 
         if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_CALLS,
                 isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_CALLS, defaultPolicy))) {
             priorityCategories |= Policy.PRIORITY_CATEGORY_CALLS;
-            callSenders = getNotificationPolicySenders(zenPolicy.getPriorityCallSenders());
+            callSenders = getNotificationPolicySenders(zenPolicy.getPriorityCallSenders(),
+                    callSenders);
         }
 
         if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_REPEAT_CALLERS,
@@ -1056,16 +1058,17 @@
         return (policy.suppressedVisualEffects & visualEffect) == 0;
     }
 
-    private int getNotificationPolicySenders(@ZenPolicy.PeopleType int senders) {
+    private int getNotificationPolicySenders(@ZenPolicy.PeopleType int senders,
+            int defaultPolicySender) {
         switch (senders) {
             case ZenPolicy.PEOPLE_TYPE_ANYONE:
                 return Policy.PRIORITY_SENDERS_ANY;
             case ZenPolicy.PEOPLE_TYPE_CONTACTS:
-
                 return Policy.PRIORITY_SENDERS_CONTACTS;
             case ZenPolicy.PEOPLE_TYPE_STARRED:
-            default:
                 return Policy.PRIORITY_SENDERS_STARRED;
+            default:
+                return defaultPolicySender;
         }
     }
 
diff --git a/core/java/android/util/StatsLog.java b/core/java/android/util/StatsLog.java
index e3de307..ace4bf4 100644
--- a/core/java/android/util/StatsLog.java
+++ b/core/java/android/util/StatsLog.java
@@ -16,6 +16,7 @@
 
 package android.util;
 
+import android.annotation.NonNull;
 import android.os.IStatsManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -113,4 +114,18 @@
         sService = IStatsManager.Stub.asInterface(ServiceManager.getService("stats"));
         return sService;
     }
+
+    /**
+     * Add a log to the stats log.
+     *
+     * @param id The id of the atom
+     * @param params The parameters of the atom's message.
+     */
+    public static void write(int id, @NonNull Object... params) {
+        switch (id) {
+            case PERMISSION_GRANT_REQUEST_RESULT_REPORTED:
+                write(id, (long) params[0], (int) params[1], (String) params[2], (String) params[3],
+                        (boolean) params[4], (int) params[5]);
+        }
+    }
 }
diff --git a/core/java/android/util/StatsLogAtoms.java b/core/java/android/util/StatsLogAtoms.java
new file mode 100644
index 0000000..bbede53
--- /dev/null
+++ b/core/java/android/util/StatsLogAtoms.java
@@ -0,0 +1,115 @@
+/*
+ * 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 android.util;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
+
+import java.lang.annotation.Retention;
+
+/**
+ * Exposed stats logs atom ids.
+ *
+ * @hide
+ */
+@SystemApi
+public class StatsLogAtoms {
+    private StatsLogAtoms() {
+    }
+
+    /**
+     * Information about a permission grant request
+     *
+     * Usage: {@code StatsLog.write(PERMISSION_GRANT_REQUEST_RESULT_REPORTED, long request_id,
+     * int requesting_uid, String requesting_package_name, String permission_name,
+     * boolean is_implicit, @PermissionGrantRequestResultReported_Result int result)}
+     */
+    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED =
+            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED;
+
+    @Retention(SOURCE)
+    @IntDef(prefix = "PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__",
+            value = {PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED,
+                    PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED,
+                    PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED,
+                    PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED,
+                    PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED,
+                    PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED,
+                    PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE,
+                    PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED})
+    public @interface PermissionGrantRequestResultReported_Result {}
+
+    /**
+     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
+     * permission request was ignored
+     */
+    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED =
+            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED;
+
+    /**
+     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
+     * permission request was ignored because it was user fixed
+     */
+    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED =
+            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED;
+
+    /**
+     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
+     * permission request was ignored because it was policy fixed
+     */
+    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED =
+            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED;
+
+    /**
+     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
+     * permission was granted by user action
+     */
+    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED =
+            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED;
+
+    /**
+     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
+     * permission was automatically granted
+     */
+    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED =
+            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED;
+
+    /**
+     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
+     * permission was denied by user action
+     */
+    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED =
+            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED;
+
+    /**
+     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
+     * permission was denied with prejudice by the user
+     */
+    public static final int
+            PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE =
+            StatsLogInternal
+                    .PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE;
+
+    /**
+     * Possible value of {@link PermissionGrantRequestResultReported_Result}:
+     * permission was automatically denied
+     */
+    public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED =
+            StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED;
+}
diff --git a/core/java/android/util/TypedValue.java b/core/java/android/util/TypedValue.java
index 99106be..7f1ee30 100644
--- a/core/java/android/util/TypedValue.java
+++ b/core/java/android/util/TypedValue.java
@@ -217,10 +217,10 @@
     public int density;
 
     /**
-     * If the Value came from a style resource, this holds the corresponding style resource id
-     * against which the attribute was resolved.
+     * If the Value came from a style resource or a layout resource (set in an XML layout), this
+     * holds the corresponding style or layout resource id against which the attribute was resolved.
      */
-    public int sourceStyleResourceId;
+    public int sourceResourceId;
 
     /* ------------------------------------------------------------ */
 
diff --git a/core/jni/android_util_XmlBlock.cpp b/core/jni/android_util_XmlBlock.cpp
index ad6bad2..1dc6834 100644
--- a/core/jni/android_util_XmlBlock.cpp
+++ b/core/jni/android_util_XmlBlock.cpp
@@ -72,7 +72,7 @@
 }
 
 static jlong android_content_XmlBlock_nativeCreateParseState(JNIEnv* env, jobject clazz,
-                                                          jlong token)
+                                                          jlong token, jint res_id)
 {
     ResXMLTree* osb = reinterpret_cast<ResXMLTree*>(token);
     if (osb == NULL) {
@@ -81,6 +81,7 @@
     }
 
     ResXMLParser* st = new ResXMLParser(*osb);
+    st->setSourceResourceId(res_id);
     if (st == NULL) {
         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
         return 0;
@@ -335,6 +336,17 @@
         ? value.data : 0;
 }
 
+static jint android_content_XmlBlock_nativeGetSourceResId(JNIEnv* env, jobject clazz,
+                                                          jlong token)
+{
+    ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token);
+    if (st == NULL) {
+        return 0;
+    } else {
+        return st->getSourceResourceId();
+    }
+}
+
 static void android_content_XmlBlock_nativeDestroyParseState(JNIEnv* env, jobject clazz,
                                                           jlong token)
 {
@@ -370,7 +382,7 @@
             (void*) android_content_XmlBlock_nativeCreate },
     { "nativeGetStringBlock",       "(J)J",
             (void*) android_content_XmlBlock_nativeGetStringBlock },
-    { "nativeCreateParseState",     "(J)J",
+    { "nativeCreateParseState",     "(JI)J",
             (void*) android_content_XmlBlock_nativeCreateParseState },
     { "nativeDestroyParseState",    "(J)V",
             (void*) android_content_XmlBlock_nativeDestroyParseState },
@@ -411,6 +423,8 @@
             (void*) android_content_XmlBlock_nativeGetClassAttribute },
     { "nativeGetStyleAttribute",   "(J)I",
             (void*) android_content_XmlBlock_nativeGetStyleAttribute },
+    { "nativeGetSourceResId",      "(J)I",
+            (void*) android_content_XmlBlock_nativeGetSourceResId},
 };
 
 int register_android_content_XmlBlock(JNIEnv* env)
diff --git a/libs/androidfw/AttributeResolution.cpp b/libs/androidfw/AttributeResolution.cpp
index 18d74ef..cc177af 100644
--- a/libs/androidfw/AttributeResolution.cpp
+++ b/libs/androidfw/AttributeResolution.cpp
@@ -286,7 +286,7 @@
     value.dataType = Res_value::TYPE_NULL;
     value.data = Res_value::DATA_NULL_UNDEFINED;
     config.density = 0;
-    uint32_t source_style_resid = 0;
+    uint32_t value_source_resid = 0;
 
     // Try to find a value for this attribute...  we prioritize values
     // coming from, first XML attributes, then XML style, then default
@@ -300,6 +300,7 @@
       if (kDebugStyles) {
         ALOGI("-> From XML: type=0x%x, data=0x%08x", value.dataType, value.data);
       }
+      value_source_resid = xml_parser->getSourceResourceId();
     }
 
     if (value.dataType == Res_value::TYPE_NULL && value.data != Res_value::DATA_NULL_EMPTY) {
@@ -310,7 +311,7 @@
         cookie = entry->cookie;
         type_set_flags = style_flags;
         value = entry->value;
-        source_style_resid = entry->style;
+        value_source_resid = entry->style;
         if (kDebugStyles) {
           ALOGI("-> From style: type=0x%x, data=0x%08x, style=0x%08x", value.dataType, value.data,
               entry->style);
@@ -330,7 +331,7 @@
           ALOGI("-> From def style: type=0x%x, data=0x%08x, style=0x%08x", value.dataType, value.data,
               entry->style);
         }
-        source_style_resid = entry->style;
+        value_source_resid = entry->style;
       }
     }
 
@@ -349,6 +350,7 @@
     } else if (value.data != Res_value::DATA_NULL_EMPTY) {
       // If we still don't have a value for this attribute, try to find it in the theme!
       ApkAssetsCookie new_cookie = theme->GetAttribute(cur_ident, &value, &type_set_flags);
+      // TODO: set value_source_resid for the style in the theme that was used.
       if (new_cookie != kInvalidCookie) {
         if (kDebugStyles) {
           ALOGI("-> From theme: type=0x%x, data=0x%08x", value.dataType, value.data);
@@ -386,7 +388,7 @@
     out_values[STYLE_RESOURCE_ID] = resid;
     out_values[STYLE_CHANGING_CONFIGURATIONS] = type_set_flags;
     out_values[STYLE_DENSITY] = config.density;
-    out_values[SYTLE_SOURCE_STYLE] = source_style_resid;
+    out_values[SYTLE_SOURCE_RESOURCE_ID] = value_source_resid;
 
     if (value.dataType != Res_value::TYPE_NULL || value.data == Res_value::DATA_NULL_EMPTY) {
       indices_idx++;
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 63b2527..11e4cb8 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -1594,6 +1594,16 @@
     mCurExt = pos.curExt;
 }
 
+void ResXMLParser::setSourceResourceId(const uint32_t resId)
+{
+    mSourceResourceId = resId;
+}
+
+uint32_t ResXMLParser::getSourceResourceId() const
+{
+    return mSourceResourceId;
+}
+
 // --------------------------------------------------------------------
 
 static volatile int32_t gCount = 0;
diff --git a/libs/androidfw/include/androidfw/AttributeResolution.h b/libs/androidfw/include/androidfw/AttributeResolution.h
index c88004c..0cc1d3c 100644
--- a/libs/androidfw/include/androidfw/AttributeResolution.h
+++ b/libs/androidfw/include/androidfw/AttributeResolution.h
@@ -33,7 +33,7 @@
   STYLE_RESOURCE_ID = 3,
   STYLE_CHANGING_CONFIGURATIONS = 4,
   STYLE_DENSITY = 5,
-  SYTLE_SOURCE_STYLE = 6
+  SYTLE_SOURCE_RESOURCE_ID = 6
 };
 
 // These are all variations of the same method. They each perform the exact same operation,
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index 1655e89..742813e 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -782,6 +782,9 @@
     void getPosition(ResXMLPosition* pos) const;
     void setPosition(const ResXMLPosition& pos);
 
+    void setSourceResourceId(const uint32_t resId);
+    uint32_t getSourceResourceId() const;
+
 private:
     friend class ResXMLTree;
     
@@ -791,6 +794,7 @@
     event_code_t                mEventCode;
     const ResXMLTree_node*      mCurNode;
     const void*                 mCurExt;
+    uint32_t                    mSourceResourceId;
 };
 
 class DynamicRefTable;
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index 297a418..7c42cc2 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -393,15 +393,6 @@
             "persist.sys.hdmi.property_sytem_audio_mode_audio_port";
 
     /**
-     * Property to indicate if a CEC audio device should forward volume keys when system audio mode
-     * is off.
-     *
-     * <p>Default is false.
-     */
-    static final String PROPERTY_CEC_AUDIO_DEVICE_FORWARD_VOLUME_KEYS_SYSTEM_AUDIO_MODE_OFF =
-            "persist.sys.hdmi.property_cec_audio_device_forward_volume_keys_system_audio_mode_off";
-
-    /**
      * Property to strip local audio of amplifier and use local speaker
      * when TV does not support system audio mode.
      *
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index f3a1e46..c5eccdf 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -1392,11 +1392,15 @@
         }
 
         @Override
+        @Nullable
         public HdmiDeviceInfo getActiveSource() {
             enforceAccessPermission();
             HdmiCecLocalDeviceTv tv = tv();
             if (tv == null) {
-                Slog.w(TAG, "Local tv device not available");
+                if (isTvDevice()) {
+                    Slog.e(TAG, "Local tv device not available.");
+                    return null;
+                }
                 if (isPlaybackDevice()) {
                     // if playback device itself is the active source,
                     // return its own device info.
@@ -1457,7 +1461,10 @@
                                     HdmiControlService.this, deviceId, callback));
                             return;
                         }
-                        Slog.w(TAG, "Local tv device not available");
+                        if (isTvDevice()) {
+                            Slog.e(TAG, "Local tv device not available");
+                            return;
+                        }
                         invokeCallback(callback, HdmiControlManager.RESULT_SOURCE_NOT_AVAILABLE);
                         return;
                     }
diff --git a/services/core/java/com/android/server/role/RoleUserState.java b/services/core/java/com/android/server/role/RoleUserState.java
index bc68dde..5030e34 100644
--- a/services/core/java/com/android/server/role/RoleUserState.java
+++ b/services/core/java/com/android/server/role/RoleUserState.java
@@ -376,7 +376,7 @@
 
             version = mVersion;
             packagesHash = mPackagesHash;
-            roles = getRoleHolders();
+            roles = snapshotRolesLocked();
         }
 
         AtomicFile atomicFile = new AtomicFile(getFile(mUserId), "roles-" + mUserId);
@@ -541,7 +541,7 @@
 
             version = mVersion;
             packagesHash = mPackagesHash;
-            roles = getRoleHolders();
+            roles = snapshotRolesLocked();
         }
 
         long fieldToken = dumpOutputStream.start(fieldName, fieldId);
@@ -578,18 +578,23 @@
     @NonNull
     public ArrayMap<String, ArraySet<String>> getRoleHolders() {
         synchronized (mLock) {
-            ArrayMap<String, ArraySet<String>> roles = new ArrayMap<>();
-            for (int i = 0, size = CollectionUtils.size(mRoles); i < size; ++i) {
-                String roleName = mRoles.keyAt(i);
-                ArraySet<String> roleHolders = mRoles.valueAt(i);
-
-                roleHolders = new ArraySet<>(roleHolders);
-                roles.put(roleName, roleHolders);
-            }
-            return roles;
+            return snapshotRolesLocked();
         }
     }
 
+    @GuardedBy("mLock")
+    private ArrayMap<String, ArraySet<String>> snapshotRolesLocked() {
+        ArrayMap<String, ArraySet<String>> roles = new ArrayMap<>();
+        for (int i = 0, size = CollectionUtils.size(mRoles); i < size; ++i) {
+            String roleName = mRoles.keyAt(i);
+            ArraySet<String> roleHolders = mRoles.valueAt(i);
+
+            roleHolders = new ArraySet<>(roleHolders);
+            roles.put(roleName, roleHolders);
+        }
+        return roles;
+    }
+
     /**
      * Destroy this user state and delete the corresponding file. Any pending writes to the file
      * will be cancelled, and any future interaction with this state will throw an exception.
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
old mode 100644
new mode 100755
index c1607e9..f08e585
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -24,7 +24,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.PackageManager;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.HdmiHotplugEvent;
@@ -46,7 +45,6 @@
 import android.media.tv.TvInputHardwareInfo;
 import android.media.tv.TvInputInfo;
 import android.media.tv.TvStreamConfig;
-import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
@@ -56,7 +54,6 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
-import android.view.KeyEvent;
 import android.view.Surface;
 
 import com.android.internal.util.DumpUtils;
@@ -943,7 +940,7 @@
                         sinkChannelMask = sinkConfig.channelMask();
                     }
                     if (sinkFormat == AudioFormat.ENCODING_DEFAULT) {
-                        sinkChannelMask = sinkConfig.format();
+                        sinkFormat = sinkConfig.format();
                     }
                 }
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
index 68d3e4c..9c7e028 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
@@ -67,7 +67,7 @@
 
     @Test
     public void testZenPolicyNothingSetToNotificationPolicy() {
-        ZenModeConfig config = getMutedAllConfig();
+        ZenModeConfig config = getCustomConfig();
         ZenPolicy zenPolicy = new ZenPolicy.Builder().build();
         assertEquals(config.toNotificationPolicy(), config.toNotificationPolicy(zenPolicy));
     }
@@ -219,6 +219,25 @@
         return config;
     }
 
+    private ZenModeConfig getCustomConfig() {
+        ZenModeConfig config = new ZenModeConfig();
+        // Some sounds allowed
+        config.allowAlarms = true;
+        config.allowMedia = false;
+        config.allowSystem = false;
+        config.allowCalls = true;
+        config.allowRepeatCallers = true;
+        config.allowMessages = false;
+        config.allowReminders = false;
+        config.allowEvents = false;
+        config.areChannelsBypassingDnd = false;
+        config.allowCallsFrom = ZenModeConfig.SOURCE_ANYONE;
+        config.allowMessagesFrom = ZenModeConfig.SOURCE_ANYONE;
+
+        config.suppressedVisualEffects = 0;
+        return config;
+    }
+
     private ZenModeConfig getMutedAllConfig() {
         ZenModeConfig config = new ZenModeConfig();
         // No sounds allowed
diff --git a/startop/view_compiler/dex_builder.cc b/startop/view_compiler/dex_builder.cc
index a78f7d5..4c1a0dc7 100644
--- a/startop/view_compiler/dex_builder.cc
+++ b/startop/view_compiler/dex_builder.cc
@@ -21,8 +21,6 @@
 #include <fstream>
 #include <memory>
 
-#define DCHECK_NOT_NULL(p) DCHECK((p) != nullptr)
-
 namespace startop {
 namespace dex {
 
@@ -32,6 +30,8 @@
 using ::dex::kAccPublic;
 using Op = Instruction::Op;
 
+using Opcode = ::art::Instruction::Code;
+
 const TypeDescriptor TypeDescriptor::Int() { return TypeDescriptor{"I"}; };
 const TypeDescriptor TypeDescriptor::Void() { return TypeDescriptor{"V"}; };
 
@@ -42,6 +42,23 @@
 // Strings lengths can be 32 bits long, but encoded as LEB128 this can take up to five bytes.
 constexpr size_t kMaxEncodedStringLength{5};
 
+// Converts invoke-* to invoke-*/range
+constexpr Opcode InvokeToInvokeRange(Opcode opcode) {
+  switch (opcode) {
+    case ::art::Instruction::INVOKE_VIRTUAL:
+      return ::art::Instruction::INVOKE_VIRTUAL_RANGE;
+    case ::art::Instruction::INVOKE_DIRECT:
+      return ::art::Instruction::INVOKE_DIRECT_RANGE;
+    case ::art::Instruction::INVOKE_STATIC:
+      return ::art::Instruction::INVOKE_STATIC_RANGE;
+    case ::art::Instruction::INVOKE_INTERFACE:
+      return ::art::Instruction::INVOKE_INTERFACE_RANGE;
+    default:
+      LOG(FATAL) << opcode << " is not a recognized invoke opcode.";
+      UNREACHABLE();
+  }
+}
+
 }  // namespace
 
 std::ostream& operator<<(std::ostream& out, const Instruction::Op& opcode) {
@@ -55,6 +72,9 @@
     case Instruction::Op::kMove:
       out << "kMove";
       return out;
+    case Instruction::Op::kMoveObject:
+      out << "kMoveObject";
+      return out;
     case Instruction::Op::kInvokeVirtual:
       out << "kInvokeVirtual";
       return out;
@@ -233,6 +253,11 @@
   return shorty;
 }
 
+const TypeDescriptor& Prototype::ArgType(size_t index) const {
+  CHECK_LT(index, param_types_.size());
+  return param_types_[index];
+}
+
 ClassBuilder::ClassBuilder(DexBuilder* parent, const std::string& name, ir::Class* class_def)
     : parent_(parent), type_descriptor_{TypeDescriptor::FromClassname(name)}, class_(class_def) {}
 
@@ -257,10 +282,10 @@
   method->access_flags = kAccPublic | ::dex::kAccStatic;
 
   auto* code = dex_->Alloc<ir::Code>();
-  DCHECK_NOT_NULL(decl_->prototype);
+  CHECK(decl_->prototype != nullptr);
   size_t const num_args =
       decl_->prototype->param_types != nullptr ? decl_->prototype->param_types->types.size() : 0;
-  code->registers = num_registers_ + num_args;
+  code->registers = num_registers_ + num_args + kMaxScratchRegisters;
   code->ins_count = num_args;
   EncodeInstructions();
   code->instructions = slicer::ArrayView<const ::dex::u2>(buffer_.data(), buffer_.size());
@@ -292,7 +317,7 @@
 }
 
 void MethodBuilder::BuildConst4(Value target, int value) {
-  DCHECK_LT(value, 16);
+  CHECK_LT(value, 16);
   AddInstruction(Instruction::OpWithArgs(Op::kMove, target, Value::Immediate(value)));
 }
 
@@ -315,6 +340,7 @@
     case Instruction::Op::kReturnObject:
       return EncodeReturn(instruction, ::art::Instruction::RETURN_OBJECT);
     case Instruction::Op::kMove:
+    case Instruction::Op::kMoveObject:
       return EncodeMove(instruction);
     case Instruction::Op::kInvokeVirtual:
       return EncodeInvoke(instruction, art::Instruction::INVOKE_VIRTUAL);
@@ -338,33 +364,43 @@
 }
 
 void MethodBuilder::EncodeReturn(const Instruction& instruction, ::art::Instruction::Code opcode) {
-  DCHECK(!instruction.dest().has_value());
+  CHECK(!instruction.dest().has_value());
   if (instruction.args().size() == 0) {
     Encode10x(art::Instruction::RETURN_VOID);
   } else {
-    DCHECK_EQ(1, instruction.args().size());
+    CHECK_EQ(1, instruction.args().size());
     size_t source = RegisterValue(instruction.args()[0]);
     Encode11x(opcode, source);
   }
 }
 
 void MethodBuilder::EncodeMove(const Instruction& instruction) {
-  DCHECK_EQ(Instruction::Op::kMove, instruction.opcode());
-  DCHECK(instruction.dest().has_value());
-  DCHECK(instruction.dest()->is_register() || instruction.dest()->is_parameter());
-  DCHECK_EQ(1, instruction.args().size());
+  CHECK(Instruction::Op::kMove == instruction.opcode() ||
+        Instruction::Op::kMoveObject == instruction.opcode());
+  CHECK(instruction.dest().has_value());
+  CHECK(instruction.dest()->is_variable());
+  CHECK_EQ(1, instruction.args().size());
 
   const Value& source = instruction.args()[0];
 
   if (source.is_immediate()) {
     // TODO: support more registers
-    DCHECK_LT(RegisterValue(*instruction.dest()), 16);
+    CHECK_LT(RegisterValue(*instruction.dest()), 16);
     Encode11n(art::Instruction::CONST_4, RegisterValue(*instruction.dest()), source.value());
   } else if (source.is_string()) {
     constexpr size_t kMaxRegisters = 256;
-    DCHECK_LT(RegisterValue(*instruction.dest()), kMaxRegisters);
-    DCHECK_LT(source.value(), 65536);  // make sure we don't need a jumbo string
+    CHECK_LT(RegisterValue(*instruction.dest()), kMaxRegisters);
+    CHECK_LT(source.value(), 65536);  // make sure we don't need a jumbo string
     Encode21c(::art::Instruction::CONST_STRING, RegisterValue(*instruction.dest()), source.value());
+  } else if (source.is_variable()) {
+    // For the moment, we only use this when we need to reshuffle registers for
+    // an invoke instruction, meaning we are too big for the 4-bit version.
+    // We'll err on the side of caution and always generate the 16-bit form of
+    // the instruction.
+    Opcode opcode = instruction.opcode() == Instruction::Op::kMove
+                        ? ::art::Instruction::MOVE_16
+                        : ::art::Instruction::MOVE_OBJECT_16;
+    Encode32x(opcode, RegisterValue(*instruction.dest()), RegisterValue(source));
   } else {
     UNIMPLEMENTED(FATAL);
   }
@@ -373,22 +409,61 @@
 void MethodBuilder::EncodeInvoke(const Instruction& instruction, ::art::Instruction::Code opcode) {
   constexpr size_t kMaxArgs = 5;
 
+  // Currently, we only support up to 5 arguments.
   CHECK_LE(instruction.args().size(), kMaxArgs);
 
   uint8_t arguments[kMaxArgs]{};
+  bool has_long_args = false;
   for (size_t i = 0; i < instruction.args().size(); ++i) {
     CHECK(instruction.args()[i].is_variable());
     arguments[i] = RegisterValue(instruction.args()[i]);
+    if (!IsShortRegister(arguments[i])) {
+      has_long_args = true;
+    }
   }
 
-  Encode35c(opcode,
-            instruction.args().size(),
-            instruction.method_id(),
-            arguments[0],
-            arguments[1],
-            arguments[2],
-            arguments[3],
-            arguments[4]);
+  if (has_long_args) {
+    // Some of the registers don't fit in the four bit short form of the invoke
+    // instruction, so we need to do an invoke/range. To do this, we need to
+    // first move all the arguments into contiguous temporary registers.
+    std::array<Value, kMaxArgs> scratch{GetScratchRegisters<kMaxArgs>()};
+
+    const auto& prototype = dex_->GetPrototypeByMethodId(instruction.method_id());
+    CHECK(prototype.has_value());
+
+    for (size_t i = 0; i < instruction.args().size(); ++i) {
+      Instruction::Op move_op;
+      if (opcode == ::art::Instruction::INVOKE_VIRTUAL ||
+          opcode == ::art::Instruction::INVOKE_DIRECT) {
+        // In this case, there is an implicit `this` argument, which is always an object.
+        if (i == 0) {
+          move_op = Instruction::Op::kMoveObject;
+        } else {
+          move_op = prototype->ArgType(i - 1).is_object() ? Instruction::Op::kMoveObject
+                                                          : Instruction::Op::kMove;
+        }
+      } else {
+        move_op = prototype->ArgType(i).is_object() ? Instruction::Op::kMoveObject
+                                                    : Instruction::Op::kMove;
+      }
+
+      EncodeMove(Instruction::OpWithArgs(move_op, scratch[i], instruction.args()[i]));
+    }
+
+    Encode3rc(InvokeToInvokeRange(opcode),
+              instruction.args().size(),
+              instruction.method_id(),
+              RegisterValue(scratch[0]));
+  } else {
+    Encode35c(opcode,
+              instruction.args().size(),
+              instruction.method_id(),
+              arguments[0],
+              arguments[1],
+              arguments[2],
+              arguments[3],
+              arguments[4]);
+  }
 
   // If there is a return value, add a move-result instruction
   if (instruction.dest().has_value()) {
@@ -416,26 +491,26 @@
 }
 
 void MethodBuilder::EncodeNew(const Instruction& instruction) {
-  DCHECK_EQ(Instruction::Op::kNew, instruction.opcode());
-  DCHECK(instruction.dest().has_value());
-  DCHECK(instruction.dest()->is_variable());
-  DCHECK_EQ(1, instruction.args().size());
+  CHECK_EQ(Instruction::Op::kNew, instruction.opcode());
+  CHECK(instruction.dest().has_value());
+  CHECK(instruction.dest()->is_variable());
+  CHECK_EQ(1, instruction.args().size());
 
   const Value& type = instruction.args()[0];
-  DCHECK_LT(RegisterValue(*instruction.dest()), 256);
-  DCHECK(type.is_type());
+  CHECK_LT(RegisterValue(*instruction.dest()), 256);
+  CHECK(type.is_type());
   Encode21c(::art::Instruction::NEW_INSTANCE, RegisterValue(*instruction.dest()), type.value());
 }
 
 void MethodBuilder::EncodeCast(const Instruction& instruction) {
-  DCHECK_EQ(Instruction::Op::kCheckCast, instruction.opcode());
-  DCHECK(instruction.dest().has_value());
-  DCHECK(instruction.dest()->is_variable());
-  DCHECK_EQ(1, instruction.args().size());
+  CHECK_EQ(Instruction::Op::kCheckCast, instruction.opcode());
+  CHECK(instruction.dest().has_value());
+  CHECK(instruction.dest()->is_variable());
+  CHECK_EQ(1, instruction.args().size());
 
   const Value& type = instruction.args()[0];
-  DCHECK_LT(RegisterValue(*instruction.dest()), 256);
-  DCHECK(type.is_type());
+  CHECK_LT(RegisterValue(*instruction.dest()), 256);
+  CHECK(type.is_type());
   Encode21c(::art::Instruction::CHECK_CAST, RegisterValue(*instruction.dest()), type.value());
 }
 
@@ -443,9 +518,9 @@
   if (value.is_register()) {
     return value.value();
   } else if (value.is_parameter()) {
-    return value.value() + num_registers_;
+    return value.value() + num_registers_ + kMaxScratchRegisters;
   }
-  DCHECK(false && "Must be either a parameter or a register");
+  CHECK(false && "Must be either a parameter or a register");
   return 0;
 }
 
@@ -498,7 +573,7 @@
     // update the index -> ir node map (see tools/dexter/slicer/dex_ir_builder.cc)
     auto new_index = dex_file_->methods_indexes.AllocateIndex();
     auto& ir_node = dex_file_->methods_map[new_index];
-    SLICER_CHECK(ir_node == nullptr);
+    CHECK(ir_node == nullptr);
     ir_node = decl;
     decl->orig_index = decl->index = new_index;
 
@@ -508,6 +583,15 @@
   return entry;
 }
 
+std::optional<const Prototype> DexBuilder::GetPrototypeByMethodId(size_t method_id) const {
+  for (const auto& entry : method_id_map_) {
+    if (entry.second.id == method_id) {
+      return entry.first.prototype;
+    }
+  }
+  return {};
+}
+
 ir::Proto* DexBuilder::GetOrEncodeProto(Prototype prototype) {
   ir::Proto*& ir_proto = proto_map_[prototype];
   if (ir_proto == nullptr) {
diff --git a/startop/view_compiler/dex_builder.h b/startop/view_compiler/dex_builder.h
index 757d863..541d800 100644
--- a/startop/view_compiler/dex_builder.h
+++ b/startop/view_compiler/dex_builder.h
@@ -16,6 +16,7 @@
 #ifndef DEX_BUILDER_H_
 #define DEX_BUILDER_H_
 
+#include <array>
 #include <forward_list>
 #include <map>
 #include <optional>
@@ -70,6 +71,8 @@
   // Return the shorty descriptor, such as I or L
   std::string short_descriptor() const { return descriptor().substr(0, 1); }
 
+  bool is_object() const { return short_descriptor() == "L"; }
+
   bool operator<(const TypeDescriptor& rhs) const { return descriptor_ < rhs.descriptor_; }
 
  private:
@@ -92,6 +95,8 @@
   // Get the shorty descriptor, such as VII for (Int, Int) -> Void
   std::string Shorty() const;
 
+  const TypeDescriptor& ArgType(size_t index) const;
+
   bool operator<(const Prototype& rhs) const {
     return std::make_tuple(return_type_, param_types_) <
            std::make_tuple(rhs.return_type_, rhs.param_types_);
@@ -124,11 +129,13 @@
 
   size_t value() const { return value_; }
 
- private:
-  enum class Kind { kLocalRegister, kParameter, kImmediate, kString, kLabel, kType };
+  constexpr Value() : value_{0}, kind_{Kind::kInvalid} {}
 
-  const size_t value_;
-  const Kind kind_;
+ private:
+  enum class Kind { kInvalid, kLocalRegister, kParameter, kImmediate, kString, kLabel, kType };
+
+  size_t value_;
+  Kind kind_;
 
   constexpr Value(size_t value, Kind kind) : value_{value}, kind_{kind} {}
 };
@@ -151,6 +158,7 @@
     kInvokeStatic,
     kInvokeVirtual,
     kMove,
+    kMoveObject,
     kNew,
     kReturn,
     kReturnObject,
@@ -172,7 +180,7 @@
 
   // A cast instruction. Basically, `(type)val`
   static inline Instruction Cast(Value val, Value type) {
-    DCHECK(type.is_type());
+    CHECK(type.is_type());
     return OpWithArgs(Op::kCheckCast, val, type);
   }
 
@@ -343,21 +351,48 @@
     buffer_.push_back(b);
   }
 
+  inline void Encode32x(art::Instruction::Code opcode, uint16_t a, uint16_t b) {
+    buffer_.push_back(opcode);
+    buffer_.push_back(a);
+    buffer_.push_back(b);
+  }
+
   inline void Encode35c(art::Instruction::Code opcode, size_t a, uint16_t b, uint8_t c, uint8_t d,
                         uint8_t e, uint8_t f, uint8_t g) {
     // a|g|op|bbbb|f|e|d|c
 
     CHECK_LE(a, 5);
-    CHECK_LT(c, 16);
-    CHECK_LT(d, 16);
-    CHECK_LT(e, 16);
-    CHECK_LT(f, 16);
-    CHECK_LT(g, 16);
+    CHECK(IsShortRegister(c));
+    CHECK(IsShortRegister(d));
+    CHECK(IsShortRegister(e));
+    CHECK(IsShortRegister(f));
+    CHECK(IsShortRegister(g));
     buffer_.push_back((a << 12) | (g << 8) | opcode);
     buffer_.push_back(b);
     buffer_.push_back((f << 12) | (e << 8) | (d << 4) | c);
   }
 
+  inline void Encode3rc(art::Instruction::Code opcode, size_t a, uint16_t b, uint16_t c) {
+    CHECK_LE(a, 255);
+    buffer_.push_back((a << 8) | opcode);
+    buffer_.push_back(b);
+    buffer_.push_back(c);
+  }
+
+  static constexpr bool IsShortRegister(size_t register_value) { return register_value < 16; }
+
+  // Returns an array of num_regs scratch registers. These are guaranteed to be
+  // contiguous, so they are suitable for the invoke-*/range instructions.
+  template <int num_regs>
+  std::array<Value, num_regs> GetScratchRegisters() const {
+    static_assert(num_regs <= kMaxScratchRegisters);
+    std::array<Value, num_regs> regs;
+    for (size_t i = 0; i < num_regs; ++i) {
+      regs[i] = std::move(Value::Local(num_registers_ + i));
+    }
+    return regs;
+  }
+
   // Converts a register or parameter to its DEX register number.
   size_t RegisterValue(const Value& value) const;
 
@@ -379,6 +414,10 @@
   // A buffer to hold instructions that have been encoded.
   std::vector<::dex::u2> buffer_;
 
+  // We create some scratch registers for when we have to shuffle registers
+  // around to make legal DEX code.
+  static constexpr size_t kMaxScratchRegisters = 5;
+
   // How many registers we've allocated
   size_t num_registers_{0};
 
@@ -447,6 +486,8 @@
   const MethodDeclData& GetOrDeclareMethod(TypeDescriptor type, const std::string& name,
                                            Prototype prototype);
 
+  std::optional<const Prototype> GetPrototypeByMethodId(size_t method_id) const;
+
  private:
   // Looks up the ir::Proto* corresponding to this given prototype, or creates one if it does not
   // exist.
diff --git a/startop/view_compiler/dex_builder_test.cc b/startop/view_compiler/dex_builder_test.cc
index 61c86b4..90c256f 100644
--- a/startop/view_compiler/dex_builder_test.cc
+++ b/startop/view_compiler/dex_builder_test.cc
@@ -140,3 +140,41 @@
 
   EXPECT_TRUE(EncodeAndVerify(&dex_file));
 }
+
+// Write out and verify a DEX file that corresponds to:
+//
+// package dextest;
+// public class DexTest {
+//     public static int foo(String s) { return s.length(); }
+// }
+TEST(DexBuilderTest, VerifyDexCallManyRegisters) {
+  DexBuilder dex_file;
+
+  auto cbuilder{dex_file.MakeClass("dextest.DexTest")};
+
+  MethodBuilder method{cbuilder.CreateMethod(
+      "foo", Prototype{TypeDescriptor::Int()})};
+
+  Value result = method.MakeRegister();
+
+  // Make a bunch of registers
+  for (size_t i = 0; i < 25; ++i) {
+    method.MakeRegister();
+  }
+
+  // Now load a string literal into a register
+  Value string_val = method.MakeRegister();
+  method.BuildConstString(string_val, "foo");
+
+  MethodDeclData string_length =
+      dex_file.GetOrDeclareMethod(TypeDescriptor::FromClassname("java.lang.String"),
+                                  "length",
+                                  Prototype{TypeDescriptor::Int()});
+
+  method.AddInstruction(Instruction::InvokeVirtual(string_length.id, result, string_val));
+  method.BuildReturn(result);
+
+  method.Encode();
+
+  EXPECT_TRUE(EncodeAndVerify(&dex_file));
+}
diff --git a/startop/view_compiler/dex_builder_test/Android.bp b/startop/view_compiler/dex_builder_test/Android.bp
index d4f38ed..ac60e96 100644
--- a/startop/view_compiler/dex_builder_test/Android.bp
+++ b/startop/view_compiler/dex_builder_test/Android.bp
@@ -15,7 +15,7 @@
 //
 
 genrule {
-    name: "generate_compiled_layout",
+    name: "generate_compiled_layout1",
     tools: [":viewcompiler"],
     cmd: "$(location :viewcompiler) $(in) --dex --out $(out) --package android.startop.test",
     srcs: ["res/layout/layout1.xml"],
@@ -24,6 +24,16 @@
     ],
 }
 
+genrule {
+    name: "generate_compiled_layout2",
+    tools: [":viewcompiler"],
+    cmd: "$(location :viewcompiler) $(in) --dex --out $(out) --package android.startop.test",
+    srcs: ["res/layout/layout2.xml"],
+    out: [
+        "layout2.dex",
+    ],
+}
+
 android_test {
     name: "dex-builder-test",
     srcs: [
@@ -31,7 +41,7 @@
         "src/android/startop/test/LayoutCompilerTest.java",
     ],
     sdk_version: "current",
-    data: [":generate_dex_testcases", ":generate_compiled_layout"],
+    data: [":generate_dex_testcases", ":generate_compiled_layout1", ":generate_compiled_layout2"],
     static_libs: [
         "android-support-test",
         "guava",
diff --git a/startop/view_compiler/dex_builder_test/AndroidTest.xml b/startop/view_compiler/dex_builder_test/AndroidTest.xml
index 68d8fdc..92e2a71 100644
--- a/startop/view_compiler/dex_builder_test/AndroidTest.xml
+++ b/startop/view_compiler/dex_builder_test/AndroidTest.xml
@@ -26,6 +26,7 @@
         <option name="push" value="trivial.dex->/data/local/tmp/dex-builder-test/trivial.dex" />
         <option name="push" value="simple.dex->/data/local/tmp/dex-builder-test/simple.dex" />
         <option name="push" value="layout1.dex->/data/local/tmp/dex-builder-test/layout1.dex" />
+        <option name="push" value="layout2.dex->/data/local/tmp/dex-builder-test/layout2.dex" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
diff --git a/startop/view_compiler/dex_builder_test/res/layout/layout2.xml b/startop/view_compiler/dex_builder_test/res/layout/layout2.xml
new file mode 100644
index 0000000..b092e1c
--- /dev/null
+++ b/startop/view_compiler/dex_builder_test/res/layout/layout2.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TableRow
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" >
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Button" />
+
+        <TableRow
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" >
+
+            <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Button" />
+            <TableRow
+                android:layout_width="match_parent"
+                android:layout_height="match_parent" >
+
+                <Button
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="Button" />
+
+                <TableRow
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent" >
+
+                    <Button
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="Button" />
+                </TableRow>
+
+            </TableRow>
+        </TableRow>
+    </TableRow>
+</LinearLayout>
diff --git a/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java b/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java
index ce3ce83..a3b1b6c 100644
--- a/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java
+++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java
@@ -36,11 +36,20 @@
     }
 
     @Test
-    public void loadAndInflaterLayout1() throws Exception {
+    public void loadAndInflateLayout1() throws Exception {
         ClassLoader dex_file = loadDexFile("layout1.dex");
         Class compiled_view = dex_file.loadClass("android.startop.test.CompiledView");
         Method layout1 = compiled_view.getMethod("layout1", Context.class, int.class);
         Context context = InstrumentationRegistry.getTargetContext();
         layout1.invoke(null, context, R.layout.layout1);
     }
+
+    @Test
+    public void loadAndInflateLayout2() throws Exception {
+        ClassLoader dex_file = loadDexFile("layout2.dex");
+        Class compiled_view = dex_file.loadClass("android.startop.test.CompiledView");
+        Method layout1 = compiled_view.getMethod("layout2", Context.class, int.class);
+        Context context = InstrumentationRegistry.getTargetContext();
+        layout1.invoke(null, context, R.layout.layout1);
+    }
 }
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 12a5344..0e17a33 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1404,8 +1404,14 @@
      *
      * @return {@code true} if there is a call which will be rejected or terminated, {@code false}
      * otherwise.
+     * @deprecated Companion apps for wearable devices should use the {@link InCallService} API
+     * instead.  Apps performing call screening should use the {@link CallScreeningService} API
+     * instead.
      */
+
+
     @RequiresPermission(Manifest.permission.ANSWER_PHONE_CALLS)
+    @Deprecated
     public boolean endCall() {
         try {
             if (isServiceConnected()) {
@@ -1426,11 +1432,15 @@
      *
      * Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE} or
      * {@link android.Manifest.permission#ANSWER_PHONE_CALLS}
+     *
+     * @deprecated Companion apps for wearable devices should use the {@link InCallService} API
+     * instead.
      */
     //TODO: L-release - need to convert all invocation of ITelecmmService#answerRingingCall to use
     // this method (clockwork & gearhead).
     @RequiresPermission(anyOf =
             {Manifest.permission.ANSWER_PHONE_CALLS, Manifest.permission.MODIFY_PHONE_STATE})
+    @Deprecated
     public void acceptRingingCall() {
         try {
             if (isServiceConnected()) {
@@ -1449,9 +1459,12 @@
      * {@link android.Manifest.permission#ANSWER_PHONE_CALLS}
      *
      * @param videoState The desired video state to answer the call with.
+     * @deprecated Companion apps for wearable devices should use the {@link InCallService} API
+     * instead.
      */
     @RequiresPermission(anyOf =
             {Manifest.permission.ANSWER_PHONE_CALLS, Manifest.permission.MODIFY_PHONE_STATE})
+    @Deprecated
     public void acceptRingingCall(int videoState) {
         try {
             if (isServiceConnected()) {