Merge "Update fonts.xml with user customization fonts."
diff --git a/api/current.txt b/api/current.txt
index 76a372a..7e0c33c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -44848,6 +44848,7 @@
     method public int compareTo(android.telephony.emergency.EmergencyNumber);
     method public int describeContents();
     method public java.lang.String getCountryIso();
+    method public int getEmergencyCallRouting();
     method public int getEmergencyNumberSourceBitmask();
     method public java.util.List<java.lang.Integer> getEmergencyNumberSources();
     method public java.util.List<java.lang.Integer> getEmergencyServiceCategories();
@@ -44858,6 +44859,9 @@
     method public boolean isInEmergencyServiceCategories(int);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.emergency.EmergencyNumber> CREATOR;
+    field public static final int EMERGENCY_CALL_ROUTING_EMERGENCY = 1; // 0x1
+    field public static final int EMERGENCY_CALL_ROUTING_NORMAL = 2; // 0x2
+    field public static final int EMERGENCY_CALL_ROUTING_UNKNOWN = 0; // 0x0
     field public static final int EMERGENCY_NUMBER_SOURCE_DATABASE = 16; // 0x10
     field public static final int EMERGENCY_NUMBER_SOURCE_DEFAULT = 8; // 0x8
     field public static final int EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG = 4; // 0x4
diff --git a/api/system-current.txt b/api/system-current.txt
index 0b7b097..cb1e96a 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6443,6 +6443,7 @@
     method public deprecated boolean getDataEnabled(int);
     method public boolean getEmergencyCallbackMode();
     method public java.lang.String getIsimDomain();
+    method public java.lang.String getIsimIst();
     method public int getPreferredNetworkTypeBitmap();
     method public int getRadioPowerState();
     method public int getSimApplicationState();
@@ -6843,6 +6844,7 @@
     method public android.os.Bundle getCallExtras();
     method public int getCallType();
     method public static int getCallTypeFromVideoState(int);
+    method public int getEmergencyCallRouting();
     method public int getEmergencyServiceCategories();
     method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
     method public int getRestrictCause();
@@ -6856,6 +6858,7 @@
     method public void setCallExtraBoolean(java.lang.String, boolean);
     method public void setCallExtraInt(java.lang.String, int);
     method public void setCallRestrictCause(int);
+    method public void setEmergencyCallRouting(int);
     method public void setEmergencyServiceCategories(int);
     method public void updateCallExtras(android.telephony.ims.ImsCallProfile);
     method public void updateCallType(android.telephony.ims.ImsCallProfile);
@@ -6985,6 +6988,7 @@
   public class ImsMmTelManager {
     method public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(android.content.Context, int);
     method public int getVoWiFiModeSetting();
+    method public int getVoWiFiRoamingModeSetting();
     method public boolean isAdvancedCallingSettingEnabled();
     method public boolean isAvailable(int, int);
     method public boolean isCapable(int, int);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 5b8261e..fdb71bb 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2158,6 +2158,7 @@
      * for helping activities determine the proper time to cancel a notification.
      *
      * @see #onUserInteraction()
+     * @see android.content.Intent#FLAG_ACTIVITY_NO_USER_ACTION
      */
     protected void onUserLeaveHint() {
     }
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 4c0ee6f..b0b8f49 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -353,6 +353,26 @@
     }
 
     /**
+     * Attempt to setup ANGLE with a (temporary) default rules file: b/121153494
+     * True: Rules file was loaded.
+     * False: Rules file was *not* loaded.
+     */
+    private boolean setupAngleRulesDebug(String packageName, String paths, String devOptIn) {
+        // b/121153494
+        // Skip APK rules file checking.
+        if (!DEBUG) {
+            Log.v(TAG, "Skipping loading the rules file.");
+            // Fill in some default values for now, so the loader can get an answer when it asks.
+            // Most importantly, we need to indicate which app we are init'ing and what the
+            // developer options for it are so we can turn on ANGLE if needed.
+            setAngleInfo(paths, packageName, devOptIn, null, 0, 0);
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
      * Attempt to setup ANGLE with a rules file loaded from the ANGLE APK.
      * True: APK rules file was loaded.
      * False: APK rules file was *not* loaded.
@@ -430,6 +450,12 @@
             return;
         }
 
+        // b/121153494
+        if (setupAngleRulesDebug(packageName, paths, devOptIn)) {
+            // We setup ANGLE with defaults, so we're done here.
+            return;
+        }
+
         if (setupAngleRulesApk(anglePkgName, angleInfo, context, packageName, paths, devOptIn)) {
             // We setup ANGLE with rules from the APK, so we're done here.
             return;
@@ -454,14 +480,19 @@
             return;
         }
 
-        String applicationPackageName = context.getPackageName();
-        String devOptInApplicationName = coreSettings.getString(
-                Settings.Global.GUP_DEV_OPT_IN_APPS);
-        boolean devOptIn = applicationPackageName.equals(devOptInApplicationName);
-        boolean whitelisted = onWhitelist(context, driverPackageName, ai.packageName);
-        if (!devOptIn && !whitelisted) {
+        if (getGlobalSettingsString(coreSettings, Settings.Global.GUP_DEV_OPT_OUT_APPS)
+                        .contains(ai.packageName)) {
             if (DEBUG) {
-                Log.w(TAG, applicationPackageName + " is not on the whitelist.");
+                Log.w(TAG, ai.packageName + " opts out from GUP.");
+            }
+            return;
+        }
+
+        if (!getGlobalSettingsString(coreSettings, Settings.Global.GUP_DEV_OPT_IN_APPS)
+                        .contains(ai.packageName)
+                && !onWhitelist(context, driverPackageName, ai.packageName)) {
+            if (DEBUG) {
+                Log.w(TAG, ai.packageName + " is not on the whitelist.");
             }
             return;
         }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 5bb5ee8..16f9a43 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -12000,12 +12000,18 @@
                 "angle_gl_driver_selection_values";
 
         /**
-         * Apps that are selected to use Game Update Package.
+         * List of Apps selected to use Game Update Packages.
          * @hide
          */
         public static final String GUP_DEV_OPT_IN_APPS = "gup_dev_opt_in_apps";
 
         /**
+         * List of Apps selected not to use Game Update Packages.
+         * @hide
+         */
+        public static final String GUP_DEV_OPT_OUT_APPS = "gup_dev_opt_out_apps";
+
+        /**
          * Apps on the black list that are forbidden to useGame Update Package.
          * @hide
          */
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index e2c23de..cdaf33f 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -232,7 +232,7 @@
     // This is the caption view for the window, containing the caption and window control
     // buttons. The visibility of this decor depends on the workspace and the window type.
     // If the window type does not require such a view, this member might be null.
-    DecorCaptionView mDecorCaptionView;
+    private DecorCaptionView mDecorCaptionView;
 
     private boolean mWindowResizeCallbacksAdded = false;
     private Drawable.Callback mLastBackgroundDrawableCb = null;
@@ -977,6 +977,7 @@
     @Override
     public void onWindowSystemUiVisibilityChanged(int visible) {
         updateColorViews(null /* insets */, true /* animate */);
+        updateDecorCaptionStatus(getResources().getConfiguration());
     }
 
     @Override
@@ -1855,8 +1856,27 @@
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
 
-        final boolean displayWindowDecor =
-                newConfig.windowConfiguration.hasWindowDecorCaption();
+        updateDecorCaptionStatus(newConfig);
+
+        updateAvailableWidth();
+        initializeElevation();
+    }
+
+    /**
+     * Determines if the workspace is entirely covered by the window.
+     * @return {@code true} when the window is filling the entire screen/workspace.
+     **/
+    private boolean isFillingScreen(Configuration config) {
+        final boolean isFullscreen = config.windowConfiguration.getWindowingMode()
+                == WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+        return isFullscreen && (0 != ((getWindowSystemUiVisibility() | getSystemUiVisibility())
+                & (View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+                | View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_LOW_PROFILE)));
+    }
+
+    private void updateDecorCaptionStatus(Configuration config) {
+        final boolean displayWindowDecor = config.windowConfiguration.hasWindowDecorCaption()
+                && !isFillingScreen(config);
         if (mDecorCaptionView == null && displayWindowDecor) {
             // Configuration now requires a caption.
             final LayoutInflater inflater = mWindow.getLayoutInflater();
@@ -1875,9 +1895,6 @@
             mDecorCaptionView.onConfigurationChanged(displayWindowDecor);
             enableCaption(displayWindowDecor);
         }
-
-        updateAvailableWidth();
-        initializeElevation();
     }
 
     void onResourcesLoaded(LayoutInflater inflater, int layoutResource) {
diff --git a/core/java/com/android/internal/widget/DecorCaptionView.java b/core/java/com/android/internal/widget/DecorCaptionView.java
index b419113..21558d3 100644
--- a/core/java/com/android/internal/widget/DecorCaptionView.java
+++ b/core/java/com/android/internal/widget/DecorCaptionView.java
@@ -319,23 +319,12 @@
         mOwner.notifyRestrictedCaptionAreaCallback(mMaximize.getLeft(), mMaximize.getTop(),
                 mClose.getRight(), mClose.getBottom());
     }
-    /**
-     * Determine if the workspace is entirely covered by the window.
-     * @return Returns true when the window is filling the entire screen/workspace.
-     **/
-    private boolean isFillingScreen() {
-        return (0 != ((getWindowSystemUiVisibility() | getSystemUiVisibility()) &
-                (View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
-                        View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_LOW_PROFILE)));
-    }
 
     /**
      * Updates the visibility of the caption.
      **/
     private void updateCaptionVisibility() {
-        // Don't show the caption if the window has e.g. entered full screen.
-        boolean invisible = isFillingScreen() || !mShow;
-        mCaption.setVisibility(invisible ? GONE : VISIBLE);
+        mCaption.setVisibility(mShow ? VISIBLE : GONE);
         mCaption.setOnTouchListener(this);
     }
 
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index d817aa3..a00fde9 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -436,11 +436,12 @@
         // Ordered GPU debug layer list for GLES
         // i.e. <layer1>:<layer2>:...:<layerN>
         optional SettingProto debug_layers_gles = 7;
-        // Apps opt in to load graphics driver from Game Update Package
-        // instead of native graphcis driver through developer options.
+        // GUP - List of Apps selected to use Game Update Packages
         optional SettingProto gup_dev_opt_in_apps = 8;
-        // Apps on the black list that are forbidden to useGame Update Package.
-        optional SettingProto gup_black_list = 9;
+        // GUP - List of Apps selected not to use Game Update Packages
+        optional SettingProto gup_dev_opt_out_apps = 9;
+        // GUP - List of Apps that are forbidden to use Game Update Packages
+        optional SettingProto gup_black_list = 10;
     }
     optional Gpu gpu = 59;
 
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 70267c7..f863356 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -478,6 +478,7 @@
                     Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS,
                     Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES,
                     Settings.Global.GUP_DEV_OPT_IN_APPS,
+                    Settings.Global.GUP_DEV_OPT_OUT_APPS,
                     Settings.Global.GUP_BLACK_LIST,
                     Settings.Global.GPU_DEBUG_LAYER_APP,
                     Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING,
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index b33cfe2..0c515a4 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -81,7 +81,7 @@
 
     explicit Matrix4(const float* v) { load(v); }
 
-    Matrix4(const SkMatrix& v) {  // NOLINT, implicit
+    Matrix4(const SkMatrix& v) {  // NOLINT(google-explicit-constructor)
         load(v);
     }
 
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index d6362ef..24443c8 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -57,15 +57,15 @@
 
     inline Rect(float width, float height) : left(0.0f), top(0.0f), right(width), bottom(height) {}
 
-    inline Rect(const SkIRect& rect)
-            :  // NOLINT, implicit
+    inline Rect(const SkIRect& rect) // NOLINT(google-explicit-constructor)
+            :
             left(rect.fLeft)
             , top(rect.fTop)
             , right(rect.fRight)
             , bottom(rect.fBottom) {}
 
-    inline Rect(const SkRect& rect)
-            :  // NOLINT, implicit
+    inline Rect(const SkRect& rect) // NOLINT(google-explicit-constructor)
+            :
             left(rect.fLeft)
             , top(rect.fTop)
             , right(rect.fRight)
diff --git a/libs/hwui/debug/GlesErrorCheckWrapper.h b/libs/hwui/debug/GlesErrorCheckWrapper.h
index ee5cc1f..791400b 100644
--- a/libs/hwui/debug/GlesErrorCheckWrapper.h
+++ b/libs/hwui/debug/GlesErrorCheckWrapper.h
@@ -24,7 +24,7 @@
 
 class GlesErrorCheckWrapper : public GlesDriver {
 public:
-    GlesErrorCheckWrapper(GlesDriver& base) : mBase(base) {}
+    explicit GlesErrorCheckWrapper(GlesDriver& base) : mBase(base) {}
 
 #define GL_ENTRY(ret, api, ...) virtual ret api##_(__VA_ARGS__) override;
 #include "gles_decls.in"
diff --git a/libs/hwui/hwui/Paint.h b/libs/hwui/hwui/Paint.h
index c1a3b6d..92ffda9 100644
--- a/libs/hwui/hwui/Paint.h
+++ b/libs/hwui/hwui/Paint.h
@@ -46,7 +46,7 @@
 
     Paint();
     Paint(const Paint& paint);
-    Paint(const SkPaint& paint);  // NOLINT(implicit)
+    Paint(const SkPaint& paint);  // NOLINT(google-explicit-constructor)
     ~Paint();
 
     Paint& operator=(const Paint& other);
diff --git a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp
index a5faae7..c3563db 100644
--- a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp
@@ -36,8 +36,6 @@
 namespace uirenderer {
 namespace skiapipeline {
 
-static std::mutex sLock{};
-static ThreadBase* sGLDrawThread = nullptr;
 static renderthread::EglManager sEglManager;
 
 // ScopedDrawRequest makes sure a GL thread is started and EGL context is initialized on it.
@@ -47,32 +45,20 @@
 
 private:
     void beginDraw() {
-        std::lock_guard _lock{sLock};
-
-        if (!sGLDrawThread) {
-            sGLDrawThread = new ThreadBase{};
-        }
-
-        if (!sGLDrawThread->isRunning()) {
-            sGLDrawThread->start("GLFunctorThread");
-        }
-
         if (!sEglManager.hasEglContext()) {
-            sGLDrawThread->queue().runSync([]() { sEglManager.initialize(); });
+            sEglManager.initialize();
         }
     }
 };
 
 void VkInteropFunctorDrawable::vkInvokeFunctor(Functor* functor) {
     ScopedDrawRequest _drawRequest{};
-    sGLDrawThread->queue().runSync([&]() {
-        EGLDisplay display = sEglManager.eglDisplay();
-        DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
-        if (display != EGL_NO_DISPLAY) {
-            mode = DrawGlInfo::kModeProcess;
-        }
-        (*functor)(mode, nullptr);
-    });
+    EGLDisplay display = sEglManager.eglDisplay();
+    DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
+    if (display != EGL_NO_DISPLAY) {
+        mode = DrawGlInfo::kModeProcess;
+    }
+    (*functor)(mode, nullptr);
 }
 
 #define FENCE_TIMEOUT 2000000000
@@ -113,7 +99,7 @@
     // TODO: draw command has completed.
     // TODO: A simple but inefficient way is to flush and issue a QueueWaitIdle call. See
     // TODO: GrVkGpu::destroyResources() for example.
-    bool success = sGLDrawThread->queue().runSync([&]() -> bool {
+    {
         ATRACE_FORMAT("WebViewDraw_%dx%d", mFBInfo.width(), mFBInfo.height());
         EGLDisplay display = sEglManager.eglDisplay();
         LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY, "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
@@ -125,7 +111,7 @@
         if (autoImage.image == EGL_NO_IMAGE_KHR) {
             ALOGW("Could not create EGL image, err =%s",
                   uirenderer::renderthread::EglManager::eglErrorString());
-            return false;
+            return;
         }
 
         AutoSkiaGlTexture glTexture;
@@ -156,7 +142,7 @@
         if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
             ALOGE("Failed framebuffer check for created target buffer: %s",
                   GLUtils::getGLFramebufferError());
-            return false;
+            return;
         }
 
         glDisable(GL_STENCIL_TEST);
@@ -183,11 +169,6 @@
         LOG_ALWAYS_FATAL_IF(waitStatus != EGL_CONDITION_SATISFIED_KHR,
                             "Failed to wait for the fence %#x", eglGetError());
         eglDestroySyncKHR(display, glDrawFinishedFence);
-        return true;
-    });
-
-    if (!success) {
-        return;
     }
 
     SkPaint paint;
@@ -208,15 +189,14 @@
     if (auto lp = std::get_if<LegacyFunctor>(&mAnyFunctor)) {
         if (lp->listener) {
             ScopedDrawRequest _drawRequest{};
-            sGLDrawThread->queue().runSync(
-                    [&]() { lp->listener->onGlFunctorReleased(lp->functor); });
+            lp->listener->onGlFunctorReleased(lp->functor);
         }
     }
 }
 
 void VkInteropFunctorDrawable::syncFunctor(const WebViewSyncData& data) const {
     ScopedDrawRequest _drawRequest{};
-    sGLDrawThread->queue().runSync([&]() { FunctorDrawable::syncFunctor(data); });
+    FunctorDrawable::syncFunctor(data);
 }
 
 }  // namespace skiapipeline
diff --git a/libs/hwui/service/GraphicsStatsService.cpp b/libs/hwui/service/GraphicsStatsService.cpp
index 29e4256..8a16b20 100644
--- a/libs/hwui/service/GraphicsStatsService.cpp
+++ b/libs/hwui/service/GraphicsStatsService.cpp
@@ -48,7 +48,7 @@
 
 class FileDescriptor {
 public:
-    FileDescriptor(int fd) : mFd(fd) {}
+    explicit FileDescriptor(int fd) : mFd(fd) {}
     ~FileDescriptor() {
         if (mFd != -1) {
             close(mFd);
@@ -56,7 +56,7 @@
         }
     }
     bool valid() { return mFd != -1; }
-    operator int() { return mFd; }
+    operator int() { return mFd; } // NOLINT(google-explicit-constructor)
 
 private:
     int mFd;
@@ -64,7 +64,7 @@
 
 class FileOutputStreamLite : public io::ZeroCopyOutputStream {
 public:
-    FileOutputStreamLite(int fd) : mCopyAdapter(fd), mImpl(&mCopyAdapter) {}
+    explicit FileOutputStreamLite(int fd) : mCopyAdapter(fd), mImpl(&mCopyAdapter) {}
     virtual ~FileOutputStreamLite() {}
 
     int GetErrno() { return mCopyAdapter.mErrno; }
@@ -82,7 +82,7 @@
         int mFd;
         int mErrno = 0;
 
-        FDAdapter(int fd) : mFd(fd) {}
+        explicit FDAdapter(int fd) : mFd(fd) {}
         virtual ~FDAdapter() {}
 
         virtual bool Write(const void* buffer, int size) override {
diff --git a/libs/hwui/utils/LinearAllocator.h b/libs/hwui/utils/LinearAllocator.h
index b401fcf..9c4a1be 100644
--- a/libs/hwui/utils/LinearAllocator.h
+++ b/libs/hwui/utils/LinearAllocator.h
@@ -168,7 +168,7 @@
     };
     // enable allocators to be constructed from other templated types
     template <class U>
-    LinearStdAllocator(const LinearStdAllocator<U>& other)  // NOLINT(implicit)
+    LinearStdAllocator(const LinearStdAllocator<U>& other)  // NOLINT(google-explicit-constructor)
             : linearAllocator(other.linearAllocator) {}
 
     T* allocate(size_t num, const void* = 0) {
diff --git a/media/java/android/media/MediaPlayer2.java b/media/java/android/media/MediaPlayer2.java
index f482f64..df96994 100644
--- a/media/java/android/media/MediaPlayer2.java
+++ b/media/java/android/media/MediaPlayer2.java
@@ -1334,11 +1334,11 @@
         return addTask(new Task(CALL_COMPLETED_SET_WAKE_LOCK, false) {
             @Override
             void process() {
-                boolean washeld = false;
+                boolean wasHeld = false;
 
                 if (mWakeLock != null) {
                     if (mWakeLock.isHeld()) {
-                        washeld = true;
+                        wasHeld = true;
                         mWakeLock.release();
                     }
                 }
@@ -1346,7 +1346,7 @@
                 mWakeLock = wakeLock;
                 if (mWakeLock != null) {
                     mWakeLock.setReferenceCounted(false);
-                    if (washeld) {
+                    if (wasHeld) {
                         mWakeLock.acquire();
                     }
                 }
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index fda0fc4..d6b6339 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -102,7 +102,6 @@
         "libhidlbase",
         "libhidlmemory",
 
-        "libpowermanager",  // Used by JWakeLock. Will be replace with public SDK API.
         "libmediametrics",  // Used by MediaMetrics. Will be replaced with stable C API.
         "libbinder",  // Used by JWakeLock and MediaMetrics.
 
diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp
index 7e6a8ab..9b4e730 100644
--- a/media/jni/android_media_MediaPlayer2.cpp
+++ b/media/jni/android_media_MediaPlayer2.cpp
@@ -86,7 +86,8 @@
 // ----------------------------------------------------------------------------
 
 struct fields_t {
-    jfieldID    context;
+    jfieldID    context;               // passed from Java to native, used for creating JWakeLock
+    jfieldID    nativeContext;         // mNativeContext in MediaPlayer2.java
     jfieldID    surface_texture;
 
     jmethodID   post_event;
@@ -225,21 +226,21 @@
 static sp<MediaPlayer2> getMediaPlayer(JNIEnv* env, jobject thiz)
 {
     Mutex::Autolock l(sLock);
-    MediaPlayer2* const p = (MediaPlayer2*)env->GetLongField(thiz, fields.context);
+    MediaPlayer2* const p = (MediaPlayer2*)env->GetLongField(thiz, fields.nativeContext);
     return sp<MediaPlayer2>(p);
 }
 
 static sp<MediaPlayer2> setMediaPlayer(JNIEnv* env, jobject thiz, const sp<MediaPlayer2>& player)
 {
     Mutex::Autolock l(sLock);
-    sp<MediaPlayer2> old = (MediaPlayer2*)env->GetLongField(thiz, fields.context);
+    sp<MediaPlayer2> old = (MediaPlayer2*)env->GetLongField(thiz, fields.nativeContext);
     if (player.get()) {
         player->incStrong((void*)setMediaPlayer);
     }
     if (old != 0) {
         old->decStrong((void*)setMediaPlayer);
     }
-    env->SetLongField(thiz, fields.context, (jlong)player.get());
+    env->SetLongField(thiz, fields.nativeContext, (jlong)player.get());
     return old;
 }
 
@@ -955,11 +956,16 @@
         return;
     }
 
-    fields.context = env->GetFieldID(clazz, "mNativeContext", "J");
+    fields.context = env->GetFieldID(clazz, "mContext", "Landroid/content/Context;");
     if (fields.context == NULL) {
         return;
     }
 
+    fields.nativeContext = env->GetFieldID(clazz, "mNativeContext", "J");
+    if (fields.nativeContext == NULL) {
+        return;
+    }
+
     fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
                                                "(Ljava/lang/Object;JIII[B)V");
     if (fields.post_event == NULL) {
@@ -1013,7 +1019,8 @@
         jint sessionId, jobject weak_this)
 {
     ALOGV("native_setup");
-    sp<MediaPlayer2> mp = MediaPlayer2::Create(sessionId);
+    jobject context = env->GetObjectField(thiz, fields.context);
+    sp<MediaPlayer2> mp = MediaPlayer2::Create(sessionId, context);
     if (mp == NULL) {
         jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
         return;
diff --git a/native/webview/plat_support/draw_functor.cpp b/native/webview/plat_support/draw_functor.cpp
index 820bac5..6c1ceab 100644
--- a/native/webview/plat_support/draw_functor.cpp
+++ b/native/webview/plat_support/draw_functor.cpp
@@ -82,13 +82,9 @@
       .onDestroyed = &onDestroyed,
   };
   if (!callbacks_initialized) {
-    switch (uirenderer::WebViewFunctor_queryPlatformRenderMode()) {
-      case uirenderer::RenderMode::OpenGL_ES:
-        webview_functor_callbacks.gles.draw = &draw_gl;
-        break;
-      case uirenderer::RenderMode::Vulkan:
-        break;
-    }
+    // Under uirenderer::RenderMode::Vulkan, whether gles or vk union should
+    // be populated should match whether the vk-gl interop is used.
+    webview_functor_callbacks.gles.draw = &draw_gl;
     callbacks_initialized = true;
   }
   SupportData* support = new SupportData{
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 7dcc3ac..03c6205 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1137,9 +1137,6 @@
     <!-- The notice header of Third-party licenses. not translatable -->
     <string name="notice_header" translatable="false"></string>
 
-    <!-- UI debug setting: opt in to use updated graphics driver? [CHAR LIMIT=100] -->
-    <string name="gup_dev_opt_in_app_summary">Opt in app to use Game Update Package in developement</string>
-
     <!-- Name of the phone device [CHAR LIMIT=NONE] -->
     <string name="media_transfer_phone_device_name">Phone speaker</string>
 </resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 526efcb..419273e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -708,6 +708,9 @@
                 Settings.Global.GUP_DEV_OPT_IN_APPS,
                 GlobalSettingsProto.Gpu.GUP_DEV_OPT_IN_APPS);
         dumpSetting(s, p,
+                Settings.Global.GUP_DEV_OPT_OUT_APPS,
+                GlobalSettingsProto.Gpu.GUP_DEV_OPT_OUT_APPS);
+        dumpSetting(s, p,
                 Settings.Global.GUP_BLACK_LIST,
                 GlobalSettingsProto.Gpu.GUP_BLACK_LIST);
         p.end(gpuToken);
diff --git a/services/backup/java/com/android/server/backup/fullbackup/AppMetadataBackupWriter.java b/services/backup/java/com/android/server/backup/fullbackup/AppMetadataBackupWriter.java
index bace1aa..d13f711 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/AppMetadataBackupWriter.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/AppMetadataBackupWriter.java
@@ -7,6 +7,7 @@
 import static com.android.server.backup.UserBackupManagerService.BACKUP_WIDGET_METADATA_TOKEN;
 
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.backup.FullBackup;
 import android.app.backup.FullBackupDataOutput;
 import android.content.pm.PackageInfo;
@@ -15,7 +16,6 @@
 import android.content.pm.SigningInfo;
 import android.os.Build;
 import android.os.Environment;
-import android.os.UserHandle;
 import android.util.Log;
 import android.util.StringBuilderPrinter;
 
@@ -254,12 +254,11 @@
      * for 'adb backup'.
      */
     // TODO(b/113807190): Investigate and potentially remove.
-    public void backupObb(PackageInfo packageInfo) {
+    public void backupObb(@UserIdInt int userId, PackageInfo packageInfo) {
         // TODO: migrate this to SharedStorageBackup, since AID_SYSTEM doesn't have access to
         // external storage.
-        // TODO: http://b/22388012
         Environment.UserEnvironment userEnv =
-                new Environment.UserEnvironment(UserHandle.USER_SYSTEM);
+                new Environment.UserEnvironment(userId);
         File obbDir = userEnv.buildExternalStorageAppObbDirs(packageInfo.packageName)[0];
         if (obbDir != null) {
             if (MORE_DEBUG) {
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
index 03d4e97..7ea1892 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
@@ -54,12 +54,12 @@
  */
 public class FullBackupEngine {
     private UserBackupManagerService backupManagerService;
-    OutputStream mOutput;
-    FullBackupPreflight mPreflightHook;
-    BackupRestoreTask mTimeoutMonitor;
-    IBackupAgent mAgent;
-    boolean mIncludeApks;
-    PackageInfo mPkg;
+    private OutputStream mOutput;
+    private FullBackupPreflight mPreflightHook;
+    private BackupRestoreTask mTimeoutMonitor;
+    private IBackupAgent mAgent;
+    private boolean mIncludeApks;
+    private PackageInfo mPkg;
     private final long mQuota;
     private final int mOpToken;
     private final int mTransportFlags;
@@ -130,7 +130,7 @@
                 // TODO(b/113807190): Look into removing, only used for 'adb backup'.
                 if (writeApk) {
                     appMetadataBackupWriter.backupApk(mPackage);
-                    appMetadataBackupWriter.backupObb(mPackage);
+                    appMetadataBackupWriter.backupObb(mUserId, mPackage);
                 }
 
                 if (DEBUG) {
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
index 43a80c4..31786d7 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
@@ -66,24 +66,22 @@
  */
 public class PerformAdbBackupTask extends FullBackupTask implements BackupRestoreTask {
 
-    private UserBackupManagerService backupManagerService;
-    FullBackupEngine mBackupEngine;
-    final AtomicBoolean mLatch;
+    private final UserBackupManagerService mUserBackupManagerService;
+    private final AtomicBoolean mLatch;
 
-    ParcelFileDescriptor mOutputFile;
-    DeflaterOutputStream mDeflater;
-    boolean mIncludeApks;
-    boolean mIncludeObbs;
-    boolean mIncludeShared;
-    boolean mDoWidgets;
-    boolean mAllApps;
-    boolean mIncludeSystem;
-    boolean mCompress;
-    boolean mKeyValue;
-    ArrayList<String> mPackages;
-    PackageInfo mCurrentTarget;
-    String mCurrentPassword;
-    String mEncryptPassword;
+    private final ParcelFileDescriptor mOutputFile;
+    private final boolean mIncludeApks;
+    private final boolean mIncludeObbs;
+    private final boolean mIncludeShared;
+    private final boolean mDoWidgets;
+    private final boolean mAllApps;
+    private final boolean mIncludeSystem;
+    private final boolean mCompress;
+    private final boolean mKeyValue;
+    private final ArrayList<String> mPackages;
+    private PackageInfo mCurrentTarget;
+    private final String mCurrentPassword;
+    private final String mEncryptPassword;
     private final int mCurrentOpToken;
 
     public PerformAdbBackupTask(UserBackupManagerService backupManagerService,
@@ -92,7 +90,7 @@
             String curPassword, String encryptPassword, boolean doAllApps, boolean doSystem,
             boolean doCompress, boolean doKeyValue, String[] packages, AtomicBoolean latch) {
         super(observer);
-        this.backupManagerService = backupManagerService;
+        mUserBackupManagerService = backupManagerService;
         mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
         mLatch = latch;
 
@@ -104,7 +102,7 @@
         mAllApps = doAllApps;
         mIncludeSystem = doSystem;
         mPackages = (packages == null)
-                ? new ArrayList<String>()
+                ? new ArrayList<>()
                 : new ArrayList<>(Arrays.asList(packages));
         mCurrentPassword = curPassword;
         // when backing up, if there is a current backup password, we require that
@@ -123,11 +121,11 @@
         mKeyValue = doKeyValue;
     }
 
-    void addPackagesToSet(TreeMap<String, PackageInfo> set, List<String> pkgNames) {
+    private void addPackagesToSet(TreeMap<String, PackageInfo> set, List<String> pkgNames) {
         for (String pkgName : pkgNames) {
             if (!set.containsKey(pkgName)) {
                 try {
-                    PackageInfo info = backupManagerService.getPackageManager().getPackageInfo(
+                    PackageInfo info = mUserBackupManagerService.getPackageManager().getPackageInfo(
                             pkgName,
                             PackageManager.GET_SIGNING_CERTIFICATES);
                     set.put(pkgName, info);
@@ -141,7 +139,7 @@
     private OutputStream emitAesBackupHeader(StringBuilder headerbuf,
             OutputStream ofstream) throws Exception {
         // User key will be used to encrypt the master key.
-        byte[] newUserSalt = backupManagerService
+        byte[] newUserSalt = mUserBackupManagerService
                 .randomBytes(PasswordUtils.PBKDF2_SALT_SIZE);
         SecretKey userKey = PasswordUtils
                 .buildPasswordKey(PBKDF_CURRENT, mEncryptPassword,
@@ -150,8 +148,8 @@
 
         // the master key is random for each backup
         byte[] masterPw = new byte[256 / 8];
-        backupManagerService.getRng().nextBytes(masterPw);
-        byte[] checksumSalt = backupManagerService
+        mUserBackupManagerService.getRng().nextBytes(masterPw);
+        byte[] checksumSalt = mUserBackupManagerService
                 .randomBytes(PasswordUtils.PBKDF2_SALT_SIZE);
 
         // primary encryption of the datastream with the random key
@@ -232,11 +230,11 @@
 
         TreeMap<String, PackageInfo> packagesToBackup = new TreeMap<>();
         FullBackupObbConnection obbConnection = new FullBackupObbConnection(
-                backupManagerService);
+                mUserBackupManagerService);
         obbConnection.establish();  // we'll want this later
 
         sendStartBackup();
-        PackageManager pm = backupManagerService.getPackageManager();
+        PackageManager pm = mUserBackupManagerService.getPackageManager();
 
         // doAllApps supersedes the package set if any
         if (mAllApps) {
@@ -245,7 +243,7 @@
             for (int i = 0; i < allPackages.size(); i++) {
                 PackageInfo pkg = allPackages.get(i);
                 // Exclude system apps if we've been asked to do so
-                if (mIncludeSystem == true
+                if (mIncludeSystem
                         || ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0)) {
                     packagesToBackup.put(pkg.packageName, pkg);
                 }
@@ -316,7 +314,7 @@
             boolean encrypting = (mEncryptPassword != null && mEncryptPassword.length() > 0);
 
             // Only allow encrypted backups of encrypted devices
-            if (backupManagerService.deviceIsEncrypted() && !encrypting) {
+            if (mUserBackupManagerService.deviceIsEncrypted() && !encrypting) {
                 Slog.e(TAG, "Unencrypted backup of encrypted device; aborting");
                 return;
             }
@@ -325,7 +323,7 @@
 
             // Verify that the given password matches the currently-active
             // backup password, if any
-            if (!backupManagerService.backupPasswordMatches(mCurrentPassword)) {
+            if (!mUserBackupManagerService.backupPasswordMatches(mCurrentPassword)) {
                 if (DEBUG) {
                     Slog.w(TAG, "Backup password mismatch; aborting");
                 }
@@ -390,7 +388,7 @@
             // Shared storage if requested
             if (mIncludeShared) {
                 try {
-                    pkg = backupManagerService.getPackageManager().getPackageInfo(
+                    pkg = mUserBackupManagerService.getPackageManager().getPackageInfo(
                             SHARED_BACKUP_AGENT_PACKAGE, 0);
                     backupQueue.add(pkg);
                 } catch (NameNotFoundException e) {
@@ -410,9 +408,17 @@
                         pkg.packageName.equals(
                                 SHARED_BACKUP_AGENT_PACKAGE);
 
-                mBackupEngine = new FullBackupEngine(backupManagerService, out,
-                        null, pkg, mIncludeApks, this, Long.MAX_VALUE,
-                        mCurrentOpToken, /*transportFlags=*/ 0);
+                FullBackupEngine mBackupEngine =
+                        new FullBackupEngine(
+                                mUserBackupManagerService,
+                                out,
+                                null,
+                                pkg,
+                                mIncludeApks,
+                                this,
+                                Long.MAX_VALUE,
+                                mCurrentOpToken,
+                                /*transportFlags=*/ 0);
                 sendOnBackupPackage(isSharedStorage ? "Shared storage" : pkg.packageName);
 
                 // Don't need to check preflight result as there is no preflight hook.
@@ -437,10 +443,10 @@
                     }
                     KeyValueAdbBackupEngine kvBackupEngine =
                             new KeyValueAdbBackupEngine(out, keyValuePackage,
-                                    backupManagerService,
-                                    backupManagerService.getPackageManager(),
-                                    backupManagerService.getBaseStateDir(),
-                                    backupManagerService.getDataDir());
+                                    mUserBackupManagerService,
+                                    mUserBackupManagerService.getPackageManager(),
+                                    mUserBackupManagerService.getBaseStateDir(),
+                                    mUserBackupManagerService.getDataDir());
                     sendOnBackupPackage(keyValuePackage.packageName);
                     kvBackupEngine.backupOnePackage();
                 }
@@ -471,7 +477,7 @@
             if (DEBUG) {
                 Slog.d(TAG, "Full backup pass complete.");
             }
-            backupManagerService.getWakelock().release();
+            mUserBackupManagerService.getWakelock().release();
         }
     }
 
@@ -493,8 +499,8 @@
             Slog.w(TAG, "adb backup cancel of " + target);
         }
         if (target != null) {
-            backupManagerService.tearDownAgentAndKill(mCurrentTarget.applicationInfo);
+            mUserBackupManagerService.tearDownAgentAndKill(mCurrentTarget.applicationInfo);
         }
-        backupManagerService.removeOperation(mCurrentOpToken);
+        mUserBackupManagerService.removeOperation(mCurrentOpToken);
     }
 }
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index f9a77af..d7cb2bd 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -68,6 +68,7 @@
         sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYER_APP, String.class);
         sGlobalSettingToTypeMap.put(Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, int.class);
         sGlobalSettingToTypeMap.put(Settings.Global.GUP_DEV_OPT_IN_APPS, String.class);
+        sGlobalSettingToTypeMap.put(Settings.Global.GUP_DEV_OPT_OUT_APPS, String.class);
         sGlobalSettingToTypeMap.put(Settings.Global.GUP_BLACK_LIST, String.class);
         // add other global settings here...
     }
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index cc57b93..bc01f7c 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -202,6 +202,9 @@
     }
 
     private void notifyPendingInsetsControlChanged() {
+        if (mPendingControlChanged.isEmpty()) {
+            return;
+        }
         mDisplayContent.mWmService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
             for (int i = mPendingControlChanged.size() - 1; i >= 0; i--) {
                 final WindowState controllingWin = mPendingControlChanged.valueAt(i);
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 1d56f04..4a553cf 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -974,10 +974,11 @@
      */
     boolean isSameIntentFilter(ActivityRecord r) {
         final Intent intent = new Intent(r.intent);
-        // Correct the activity intent for aliasing. The task record intent will always be based on
-        // the real activity that will be launched not the alias, so we need to use an intent with
-        // the component name pointing to the real activity not the alias in the activity record.
-        intent.setComponent(r.mActivityComponent);
+        // Make sure the component are the same if the input activity has the same real activity
+        // as the one in the task because either one of them could be the alias activity.
+        if (Objects.equals(realActivity, r.mActivityComponent) && this.intent != null) {
+            intent.setComponent(this.intent.getComponent());
+        }
         return intent.filterEquals(this.intent);
     }
 
diff --git a/services/robotests/backup/src/com/android/server/backup/fullbackup/AppMetadataBackupWriterTest.java b/services/robotests/backup/src/com/android/server/backup/fullbackup/AppMetadataBackupWriterTest.java
index 423512c..aca48b6 100644
--- a/services/robotests/backup/src/com/android/server/backup/fullbackup/AppMetadataBackupWriterTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/fullbackup/AppMetadataBackupWriterTest.java
@@ -12,6 +12,7 @@
 import static org.testng.Assert.expectThrows;
 
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.Application;
 import android.app.backup.BackupDataInput;
 import android.app.backup.FullBackupDataOutput;
@@ -62,6 +63,7 @@
     private static final String TEST_PACKAGE_INSTALLER = "com.test.package.installer";
     private static final Long TEST_PACKAGE_VERSION_CODE = 100L;
 
+    private @UserIdInt int mUserId;
     private PackageManager mPackageManager;
     private ShadowApplicationPackageManager mShadowPackageManager;
     private File mFilesDir;
@@ -72,6 +74,7 @@
     public void setUp() throws Exception {
         Application application = RuntimeEnvironment.application;
 
+        mUserId = UserHandle.USER_SYSTEM;
         mPackageManager = application.getPackageManager();
         mShadowPackageManager = (ShadowApplicationPackageManager) shadowOf(mPackageManager);
 
@@ -352,7 +355,7 @@
         byte[] obbBytes = "obb".getBytes();
         File obbFile = createObbFileAndWrite(obbDir, obbBytes);
 
-        mBackupWriter.backupObb(packageInfo);
+        mBackupWriter.backupObb(mUserId, packageInfo);
 
         byte[] writtenBytes = getWrittenBytes(mBackupDataOutputFile, /* includeTarHeader */ false);
         assertThat(writtenBytes).isEqualTo(obbBytes);
@@ -366,7 +369,7 @@
         File obbDir = createObbDirForPackage(packageInfo.packageName);
         // No obb file created.
 
-        mBackupWriter.backupObb(packageInfo);
+        mBackupWriter.backupObb(mUserId, packageInfo);
 
         assertThat(mBackupDataOutputFile.length()).isEqualTo(0);
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index ee336a8..bd29d2a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -169,6 +169,7 @@
         private final ActivityTaskManagerService mService;
 
         private ComponentName mComponent;
+        private String mTargetActivity;
         private TaskRecord mTaskRecord;
         private int mUid;
         private boolean mCreateTask;
@@ -185,6 +186,11 @@
             return this;
         }
 
+        ActivityBuilder setTargetActivity(String targetActivity) {
+            mTargetActivity = targetActivity;
+            return this;
+        }
+
         static ComponentName getDefaultComponent() {
             return ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
                     DEFAULT_COMPONENT_PACKAGE_NAME);
@@ -239,6 +245,10 @@
             aInfo.applicationInfo = new ApplicationInfo();
             aInfo.applicationInfo.packageName = mComponent.getPackageName();
             aInfo.applicationInfo.uid = mUid;
+            aInfo.packageName = mComponent.getPackageName();
+            if (mTargetActivity != null) {
+                aInfo.targetActivity = mTargetActivity;
+            }
             aInfo.flags |= mActivityFlags;
             aInfo.launchMode = mLaunchMode;
 
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 00bec3f..8a98cbe 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -268,19 +268,38 @@
     /** Ensures that the alias intent won't have target component resolved. */
     @Test
     public void testTaskIntentActivityAlias() {
-        final String aliasActivity = DEFAULT_COMPONENT_PACKAGE_NAME + ".aliasActivity";
-        final String targetActivity = DEFAULT_COMPONENT_PACKAGE_NAME + ".targetActivity";
+        final String aliasClassName = DEFAULT_COMPONENT_PACKAGE_NAME + ".aliasActivity";
+        final String targetClassName = DEFAULT_COMPONENT_PACKAGE_NAME + ".targetActivity";
+        final ComponentName aliasComponent =
+                new ComponentName(DEFAULT_COMPONENT_PACKAGE_NAME, aliasClassName);
+        final ComponentName targetComponent =
+                new ComponentName(DEFAULT_COMPONENT_PACKAGE_NAME, targetClassName);
+
         final Intent intent = new Intent();
-        intent.setComponent(new ComponentName(DEFAULT_COMPONENT_PACKAGE_NAME, aliasActivity));
+        intent.setComponent(aliasComponent);
         final ActivityInfo info = new ActivityInfo();
         info.applicationInfo = new ApplicationInfo();
         info.packageName = DEFAULT_COMPONENT_PACKAGE_NAME;
-        info.targetActivity = targetActivity;
+        info.targetActivity = targetClassName;
 
         final TaskRecord task = TaskRecord.create(mService, 1 /* taskId */, info, intent,
                 null /* taskDescription */);
-        assertEquals("The alias activity component should be saved in task intent.", aliasActivity,
+        assertEquals("The alias activity component should be saved in task intent.", aliasClassName,
                 task.intent.getComponent().getClassName());
+
+        ActivityRecord aliasActivity = new ActivityBuilder(mService).setComponent(
+                aliasComponent).setTargetActivity(targetClassName).build();
+        assertEquals("Should be the same intent filter.", true,
+                task.isSameIntentFilter(aliasActivity));
+
+        ActivityRecord targetActivity = new ActivityBuilder(mService).setComponent(
+                targetComponent).build();
+        assertEquals("Should be the same intent filter.", true,
+                task.isSameIntentFilter(targetActivity));
+
+        ActivityRecord defaultActivity = new ActivityBuilder(mService).build();
+        assertEquals("Should not be the same intent filter.", false,
+                task.isSameIntentFilter(defaultActivity));
     }
 
     private void testStackBoundsConfiguration(int windowingMode, Rect parentBounds, Rect bounds,
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 6402ec4..6484005 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -5858,9 +5858,14 @@
 
     /**
      * Returns the IMS Service Table (IST) that was loaded from the ISIM.
+     *
+     * See 3GPP TS 31.103 (Section 4.2.7) for the definition and more information on this table.
+     *
      * @return IMS Service Table or null if not present or not loaded
      * @hide
      */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public String getIsimIst() {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
diff --git a/telephony/java/android/telephony/emergency/EmergencyNumber.java b/telephony/java/android/telephony/emergency/EmergencyNumber.java
index fe062d5..a94b163 100644
--- a/telephony/java/android/telephony/emergency/EmergencyNumber.java
+++ b/telephony/java/android/telephony/emergency/EmergencyNumber.java
@@ -29,6 +29,7 @@
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -198,21 +199,53 @@
         EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_DEFAULT);
     }
 
+    /**
+     * Indicated the framework does not know whether an emergency call should be placed using
+     * emergency or normal call routing. This means the underlying radio or IMS implementation is
+     * free to determine for itself how to route the call.
+     */
+    public static final int EMERGENCY_CALL_ROUTING_UNKNOWN = 0;
+    /**
+     * Indicates the radio or IMS implementation must handle the call through emergency routing.
+     */
+    public static final int EMERGENCY_CALL_ROUTING_EMERGENCY = 1;
+    /**
+     * Indicates the radio or IMS implementation must handle the call through normal call routing.
+     */
+    public static final int EMERGENCY_CALL_ROUTING_NORMAL = 2;
+
+    /**
+     * The routing to tell how to handle the call for the corresponding emergency number.
+     *
+     * @hide
+     */
+    @IntDef(flag = false, prefix = { "EMERGENCY_CALL_ROUTING_" }, value = {
+            EMERGENCY_CALL_ROUTING_UNKNOWN,
+            EMERGENCY_CALL_ROUTING_EMERGENCY,
+            EMERGENCY_CALL_ROUTING_NORMAL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EmergencyCallRouting {}
+
+
     private final String mNumber;
     private final String mCountryIso;
     private final String mMnc;
     private final int mEmergencyServiceCategoryBitmask;
     private final int mEmergencyNumberSourceBitmask;
+    private final int mEmergencyCallRouting;
 
     /** @hide */
-    public EmergencyNumber(@NonNull String number, @NonNull String countryIso,
-                           @NonNull String mnc, int emergencyServiceCategories,
-                           int emergencyNumberSources) {
+    public EmergencyNumber(@NonNull String number, @NonNull String countryIso, @NonNull String mnc,
+                           @EmergencyServiceCategories int emergencyServiceCategories,
+                           @EmergencyNumberSources int emergencyNumberSources,
+                           @EmergencyCallRouting int emergencyCallRouting) {
         this.mNumber = number;
         this.mCountryIso = countryIso;
         this.mMnc = mnc;
         this.mEmergencyServiceCategoryBitmask = emergencyServiceCategories;
         this.mEmergencyNumberSourceBitmask = emergencyNumberSources;
+        this.mEmergencyCallRouting = emergencyCallRouting;
     }
 
     /** @hide */
@@ -222,8 +255,33 @@
         mMnc = source.readString();
         mEmergencyServiceCategoryBitmask = source.readInt();
         mEmergencyNumberSourceBitmask = source.readInt();
+        mEmergencyCallRouting = source.readInt();
     }
 
+    @Override
+    /** @hide */
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mNumber);
+        dest.writeString(mCountryIso);
+        dest.writeString(mMnc);
+        dest.writeInt(mEmergencyServiceCategoryBitmask);
+        dest.writeInt(mEmergencyNumberSourceBitmask);
+        dest.writeInt(mEmergencyCallRouting);
+    }
+
+    public static final Parcelable.Creator<EmergencyNumber> CREATOR =
+            new Parcelable.Creator<EmergencyNumber>() {
+                @Override
+                public EmergencyNumber createFromParcel(Parcel in) {
+                    return new EmergencyNumber(in);
+                }
+
+                @Override
+                public EmergencyNumber[] newArray(int size) {
+                    return new EmergencyNumber[size];
+                }
+            };
+
     /**
      * Get the dialing number of the emergency number.
      *
@@ -352,14 +410,17 @@
         return (mEmergencyNumberSourceBitmask & sources) == sources;
     }
 
-    @Override
-    /** @hide */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(mNumber);
-        dest.writeString(mCountryIso);
-        dest.writeString(mMnc);
-        dest.writeInt(mEmergencyServiceCategoryBitmask);
-        dest.writeInt(mEmergencyNumberSourceBitmask);
+    /**
+     * Returns the emergency call routing information.
+     *
+     * <p>Some regions require some emergency numbers which are not routed using typical emergency
+     * call processing, but are instead placed as regular phone calls. The emergency call routing
+     * field provides information about how an emergency call will be routed when it is placed.
+     *
+     * @return the emergency call routing requirement
+     */
+    public @EmergencyCallRouting int getEmergencyCallRouting() {
+        return mEmergencyCallRouting;
     }
 
     @Override
@@ -373,7 +434,8 @@
         return "EmergencyNumber:" + "Number-" + mNumber + "|CountryIso-" + mCountryIso
                 + "|Mnc-" + mMnc
                 + "|ServiceCategories-" + Integer.toBinaryString(mEmergencyServiceCategoryBitmask)
-                + "|Sources-" + Integer.toBinaryString(mEmergencyNumberSourceBitmask);
+                + "|Sources-" + Integer.toBinaryString(mEmergencyNumberSourceBitmask)
+                + "|Routing-" + Integer.toBinaryString(mEmergencyCallRouting);
     }
 
     @Override
@@ -381,7 +443,19 @@
         if (!EmergencyNumber.class.isInstance(o)) {
             return false;
         }
-        return (o == this || toString().equals(o.toString()));
+        EmergencyNumber other = (EmergencyNumber) o;
+        return mNumber.equals(other.mNumber)
+                && mCountryIso.equals(other.mCountryIso)
+                && mMnc.equals(other.mMnc)
+                && mEmergencyServiceCategoryBitmask == other.mEmergencyServiceCategoryBitmask
+                && mEmergencyNumberSourceBitmask == other.mEmergencyNumberSourceBitmask
+                && mEmergencyCallRouting == other.mEmergencyCallRouting;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mNumber, mCountryIso, mMnc, mEmergencyServiceCategoryBitmask,
+                mEmergencyNumberSourceBitmask, mEmergencyCallRouting);
     }
 
     /**
@@ -462,12 +536,12 @@
                 continue;
             }
             for (int j = i + 1; j < emergencyNumberList.size(); j++) {
-                if (isSameEmergencyNumber(
+                if (areSameEmergencyNumbers(
                         emergencyNumberList.get(i), emergencyNumberList.get(j))) {
                     Rlog.e(LOG_TAG, "Found unexpected duplicate numbers: "
                             + emergencyNumberList.get(i) + " vs " + emergencyNumberList.get(j));
                     // Set the merged emergency number in the current position
-                    emergencyNumberList.set(i, mergeNumbers(
+                    emergencyNumberList.set(i, mergeSameEmergencyNumbers(
                             emergencyNumberList.get(i), emergencyNumberList.get(j)));
                     // Mark the emergency number has been merged
                     mergedEmergencyNumber.add(emergencyNumberList.get(j));
@@ -486,8 +560,8 @@
      * Check if two emergency numbers are the same.
      *
      * A unique EmergencyNumber has a unique combination of ‘number’, ‘mcc’, 'mnc' and
-     * 'categories' fields. Multiple Emergency Number Sources should be merged into one bitfield
-     * for the same EmergencyNumber.
+     * 'categories', and 'routing' fields. Multiple Emergency Number Sources should be
+     * merged into one bitfield for the same EmergencyNumber.
      *
      * @param first first EmergencyNumber to compare
      * @param second second EmergencyNumber to compare
@@ -495,8 +569,8 @@
      *
      * @hide
      */
-    public static boolean isSameEmergencyNumber(@NonNull EmergencyNumber first,
-                                                @NonNull EmergencyNumber second) {
+    public static boolean areSameEmergencyNumbers(@NonNull EmergencyNumber first,
+                                                  @NonNull EmergencyNumber second) {
         if (!first.getNumber().equals(second.getNumber())) {
             return false;
         }
@@ -510,11 +584,15 @@
                 != second.getEmergencyServiceCategoryBitmask()) {
             return false;
         }
+        if (first.getEmergencyCallRouting() != second.getEmergencyCallRouting()) {
+            return false;
+        }
         return true;
     }
 
     /**
-     * Get a merged EmergencyNumber for two numbers if they are the same.
+     * Get a merged EmergencyNumber from two same emergency numbers. Two emergency numbers are
+     * the same if {@link #areSameEmergencyNumbers} returns {@code true}.
      *
      * @param first first EmergencyNumber to compare
      * @param second second EmergencyNumber to compare
@@ -522,27 +600,15 @@
      *
      * @hide
      */
-    public static EmergencyNumber mergeNumbers(@NonNull EmergencyNumber first,
-                                         @NonNull EmergencyNumber second) {
-        if (isSameEmergencyNumber(first, second)) {
+    public static EmergencyNumber mergeSameEmergencyNumbers(@NonNull EmergencyNumber first,
+                                                            @NonNull EmergencyNumber second) {
+        if (areSameEmergencyNumbers(first, second)) {
             return new EmergencyNumber(first.getNumber(), first.getCountryIso(), first.getMnc(),
                     first.getEmergencyServiceCategoryBitmask(),
                     first.getEmergencyNumberSourceBitmask()
-                            | second.getEmergencyNumberSourceBitmask());
+                            | second.getEmergencyNumberSourceBitmask(),
+                    first.getEmergencyCallRouting());
         }
         return null;
     }
-
-    public static final Parcelable.Creator<EmergencyNumber> CREATOR =
-            new Parcelable.Creator<EmergencyNumber>() {
-        @Override
-        public EmergencyNumber createFromParcel(Parcel in) {
-            return new EmergencyNumber(in);
-        }
-
-        @Override
-        public EmergencyNumber[] newArray(int size) {
-            return new EmergencyNumber[size];
-        }
-    };
 }
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index cb6fcd7..9c8d078 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -24,9 +24,11 @@
 import android.os.Parcelable;
 import android.telecom.VideoProfile;
 import android.telephony.emergency.EmergencyNumber;
+import android.telephony.emergency.EmergencyNumber.EmergencyCallRouting;
 import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
 import android.util.Log;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.PhoneConstants;
 
 import java.lang.annotation.Retention;
@@ -321,6 +323,20 @@
             EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;
 
     /**
+     * The emergency call routing, only valid if {@link #getServiceType} returns
+     * {@link #SERVICE_TYPE_EMERGENCY}
+     *
+     * If valid, the value is any of the following constants:
+     * <ol>
+     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_UNKNOWN} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_NORMAL} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_EMERGENCY} </li>
+     * </ol>
+     */
+    private @EmergencyCallRouting int mEmergencyCallRouting =
+            EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
+
+    /**
      * Extras associated with this {@link ImsCallProfile}.
      * <p>
      * Valid data types include:
@@ -503,10 +519,12 @@
 
     @Override
     public String toString() {
-        return "{ serviceType=" + mServiceType +
-                ", callType=" + mCallType +
-                ", restrictCause=" + mRestrictCause +
-                ", mediaProfile=" + mMediaProfile.toString() + " }";
+        return "{ serviceType=" + mServiceType
+                + ", callType=" + mCallType
+                + ", restrictCause=" + mRestrictCause
+                + ", mediaProfile=" + mMediaProfile.toString()
+                + ", emergencyServiceCategories=" + mEmergencyCallRouting
+                + ", emergencyCallRouting=" + mEmergencyCallRouting + " }";
     }
 
     @Override
@@ -522,6 +540,7 @@
         out.writeBundle(filteredExtras);
         out.writeParcelable(mMediaProfile, 0);
         out.writeInt(mEmergencyServiceCategories);
+        out.writeInt(mEmergencyCallRouting);
     }
 
     private void readFromParcel(Parcel in) {
@@ -530,6 +549,7 @@
         mCallExtras = in.readBundle();
         mMediaProfile = in.readParcelable(ImsStreamMediaProfile.class.getClassLoader());
         mEmergencyServiceCategories = in.readInt();
+        mEmergencyCallRouting = in.readInt();
     }
 
     public static final Creator<ImsCallProfile> CREATOR = new Creator<ImsCallProfile>() {
@@ -740,6 +760,21 @@
     }
 
     /**
+     * Set the emergency service categories and emergency call routing. The set value is valid
+     * only if {@link #getServiceType} returns {@link #SERVICE_TYPE_EMERGENCY}
+     *
+     * Reference: 3gpp 23.167, Section 6 - Functional description;
+     *            3gpp 22.101, Section 10 - Emergency Calls.
+     *
+     * @hide
+     */
+    public void setEmergencyCallInfo(EmergencyNumber num) {
+        setEmergencyServiceCategories(num.getEmergencyServiceCategoryBitmask());
+        setEmergencyCallRouting(num.getEmergencyCallRouting());
+    }
+
+
+    /**
      * Set the emergency service categories. The set value is valid only if
      * {@link #getServiceType} returns {@link #SERVICE_TYPE_EMERGENCY}
      *
@@ -758,12 +793,29 @@
      * Reference: 3gpp 23.167, Section 6 - Functional description;
      *            3gpp 22.101, Section 10 - Emergency Calls.
      */
+    @VisibleForTesting
     public void setEmergencyServiceCategories(
             @EmergencyServiceCategories int emergencyServiceCategories) {
         mEmergencyServiceCategories = emergencyServiceCategories;
     }
 
     /**
+     * Set the emergency call routing, only valid if {@link #getServiceType} returns
+     * {@link #SERVICE_TYPE_EMERGENCY}
+     *
+     * If valid, the value is any of the following constants:
+     * <ol>
+     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_UNKNOWN} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_NORMAL} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_EMERGENCY} </li>
+     * </ol>
+     */
+    @VisibleForTesting
+    public void setEmergencyCallRouting(@EmergencyCallRouting int emergencyCallRouting) {
+        mEmergencyCallRouting = emergencyCallRouting;
+    }
+
+    /**
      * Get the emergency service categories, only valid if {@link #getServiceType} returns
      * {@link #SERVICE_TYPE_EMERGENCY}
      *
@@ -787,4 +839,19 @@
     public @EmergencyServiceCategories int getEmergencyServiceCategories() {
         return mEmergencyServiceCategories;
     }
+
+    /**
+     * Get the emergency call routing, only valid if {@link #getServiceType} returns
+     * {@link #SERVICE_TYPE_EMERGENCY}
+     *
+     * If valid, the value is any of the following constants:
+     * <ol>
+     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_UNKNOWN} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_NORMAL} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_CALL_ROUTING_EMERGENCY} </li>
+     * </ol>
+     */
+    public @EmergencyCallRouting int getEmergencyCallRouting() {
+        return mEmergencyCallRouting;
+    }
 }
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index 122626f..e2350fe 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -714,7 +714,7 @@
      * @see #setVoWiFiRoamingSetting(boolean)
      */
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    @WiFiCallingMode int getVoWiFiRoamingModeSetting() {
+    public @WiFiCallingMode int getVoWiFiRoamingModeSetting() {
         try {
             return getITelephony().getVoWiFiRoamingModeSetting(mSubId);
         } catch (RemoteException e) {