Merge "Add 1.05 and 1.2 as new possible font scale values" into 24D1-dev
diff --git a/data/keyboards/Vendor_054c_Product_05c4.idc b/data/keyboards/Vendor_054c_Product_05c4.idc
index 2cb3f7b..2da6227 100644
--- a/data/keyboards/Vendor_054c_Product_05c4.idc
+++ b/data/keyboards/Vendor_054c_Product_05c4.idc
@@ -13,9 +13,11 @@
 # limitations under the License.
 
 #
-# Sony DS4 motion sensor configuration file.
+# Sony Playstation(R) DualShock 4 Controller
 #
 
+## Motion sensor ##
+
 # reporting mode 0 - continuous
 sensor.accelerometer.reportingMode = 0
 # The delay between sensor events corresponding to the lowest frequency in microsecond
@@ -33,3 +35,28 @@
 sensor.gyroscope.minDelay = 5000
 # The power in mA used by this sensor while in use
 sensor.gyroscope.power = 0.8
+
+## Touchpad ##
+
+# After the DualShock 4 has been connected over Bluetooth for a minute or so,
+# its reports start bunching up in time, meaning that we receive 2–4 reports
+# within a millisecond followed by a >10ms wait until the next batch.
+#
+# This uneven timing causes the apparent speed of a finger (calculated using
+# time deltas between received reports) to vary dramatically even if it's
+# actually moving smoothly across the touchpad, triggering the touchpad stack's
+# drumroll detection logic. For moving fingers, the drumroll detection logic
+# splits the finger's single movement into many small movements of consecutive
+# touches, which are then inhibited by the click wiggle filter. For tapping
+# fingers, it prevents tapping to click because it thinks the finger's moving
+# too fast.
+#
+# Since this touchpad doesn't seem to have to drumroll issues, we can safely
+# disable drumroll detection.
+gestureProp.Drumroll_Suppression_Enable = 0
+
+# Because of the way this touchpad is positioned, touches around the edges are
+# no more likely to be palms than ones in the middle, so remove the edge zones
+# from the palm classifier to increase the usable area of the pad.
+gestureProp.Palm_Edge_Zone_Width = 0
+gestureProp.Tap_Exclusion_Border_Width = 0
diff --git a/data/keyboards/Vendor_054c_Product_09cc.idc b/data/keyboards/Vendor_054c_Product_09cc.idc
index 2cb3f7b..2a1a4fc 100644
--- a/data/keyboards/Vendor_054c_Product_09cc.idc
+++ b/data/keyboards/Vendor_054c_Product_09cc.idc
@@ -13,9 +13,11 @@
 # limitations under the License.
 
 #
-# Sony DS4 motion sensor configuration file.
+# Sony Playstation(R) DualShock 4 Controller
 #
 
+## Motion sensor ##
+
 # reporting mode 0 - continuous
 sensor.accelerometer.reportingMode = 0
 # The delay between sensor events corresponding to the lowest frequency in microsecond
@@ -33,3 +35,28 @@
 sensor.gyroscope.minDelay = 5000
 # The power in mA used by this sensor while in use
 sensor.gyroscope.power = 0.8
+
+## Touchpad ##
+
+# After the DualShock 4 has been connected over Bluetooth for a minute or so,
+# its reports start bunching up in time, meaning that we receive 2–4 reports
+# within a millisecond followed by a >10ms wait until the next batch.
+#
+# This uneven timing causes the apparent speed of a finger (calculated using
+# time deltas between received reports) to vary dramatically even if it's
+# actually moving smoothly across the touchpad, triggering the touchpad stack's
+# drumroll detection logic. For moving fingers, the drumroll detection logic
+# splits the finger's single movement into many small movements of consecutive
+# touches, which are then inhibited by the click wiggle filter. For tapping
+# fingers, it prevents tapping to click because it thinks the finger's moving
+# too fast.
+#
+# Since this touchpad doesn't seem to have drumroll issues, we can safely
+# disable drumroll detection.
+gestureProp.Drumroll_Suppression_Enable = 0
+
+# Because of the way this touchpad is positioned, touches around the edges are
+# no more likely to be palms than ones in the middle, so remove the edge zones
+# from the palm classifier to increase the usable area of the pad.
+gestureProp.Palm_Edge_Zone_Width = 0
+gestureProp.Tap_Exclusion_Border_Width = 0
diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml
index 8baaf2f..38ee6e2 100644
--- a/libs/WindowManager/Shell/res/values/config.xml
+++ b/libs/WindowManager/Shell/res/values/config.xml
@@ -45,9 +45,6 @@
     <!-- Allow PIP to resize to a slightly bigger state upon touch/showing the menu -->
     <bool name="config_pipEnableResizeForMenu">true</bool>
 
-    <!-- PiP minimum size, which is a % based off the shorter side of display width and height -->
-    <fraction name="config_pipShortestEdgePercent">40%</fraction>
-
     <!-- Time (duration in milliseconds) that the shell waits for an app to close the PiP by itself
          if a custom action is present before closing it. -->
     <integer name="config_pipForceCloseDelay">1000</integer>
@@ -91,11 +88,45 @@
         16x16
     </string>
 
+    <!-- Default percentages for the PIP size logic.
+         1. Determine max widths
+         Subtract width of system UI and default padding from the shortest edge of the device.
+         This is the max width.
+         2. Calculate Default and Mins
+         Default is config_pipSystemPreferredDefaultSizePercent of max-width/height.
+         Min is config_pipSystemPreferredMinimumSizePercent of it. -->
+    <item name="config_pipSystemPreferredDefaultSizePercent" format="float" type="dimen">0.6</item>
+    <item name="config_pipSystemPreferredMinimumSizePercent" format="float" type="dimen">0.5</item>
+    <!-- Default percentages for the PIP size logic when the Display is close to square.
+         This is used instead when the display is square-ish, like fold-ables when unfolded,
+         to make sure that default PiP does not cover the hinge (halfway of the display).
+         0. Determine if the display is square-ish
+         If min(displayWidth, displayHeight) / max(displayWidth, displayHeight) is greater than
+         config_pipSquareDisplayThresholdForSystemPreferredSize, we use the percent for
+         square display listed below.
+         1. Determine max widths
+         Subtract width of system UI and default padding from the shortest edge of the device.
+         This is the max width.
+         2. Calculate Default and Mins
+         Default is config_pipSystemPreferredDefaultSizePercentForSquareDisplay of max-width/height.
+         Min is config_pipSystemPreferredMinimumSizePercentForSquareDisplay of it. -->
+    <item name="config_pipSquareDisplayThresholdForSystemPreferredSize"
+        format="float" type="dimen">0.95</item>
+    <item name="config_pipSystemPreferredDefaultSizePercentForSquareDisplay"
+        format="float" type="dimen">0.5</item>
+    <item name="config_pipSystemPreferredMinimumSizePercentForSquareDisplay"
+        format="float" type="dimen">0.4</item>
+
     <!-- The percentage of the screen width to use for the default width or height of
          picture-in-picture windows. Regardless of the percent set here, calculated size will never
-         be smaller than @dimen/default_minimal_size_pip_resizable_task. -->
+         be smaller than @dimen/default_minimal_size_pip_resizable_task.
+         This is used in legacy spec, use config_pipSystemPreferredDefaultSizePercent instead. -->
     <item name="config_pictureInPictureDefaultSizePercent" format="float" type="dimen">0.23</item>
 
+    <!-- PiP minimum size, which is a % based off the shorter side of display width and height.
+         This is used in legacy spec, use config_pipSystemPreferredMinimumSizePercent instead. -->
+    <fraction name="config_pipShortestEdgePercent">40%</fraction>
+
     <!-- The default aspect ratio for picture-in-picture windows. -->
     <item name="config_pictureInPictureDefaultAspectRatio" format="float" type="dimen">
         1.777778
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PhoneSizeSpecSource.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PhoneSizeSpecSource.kt
index 18c7bdd..7eb0f26 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PhoneSizeSpecSource.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PhoneSizeSpecSource.kt
@@ -18,7 +18,6 @@
 
 import android.content.Context
 import android.content.res.Resources
-import android.os.SystemProperties
 import android.util.Size
 import com.android.wm.shell.R
 import java.io.PrintWriter
@@ -36,30 +35,81 @@
     private var mOverrideMinSize: Size? = null
 
 
-    /** Default and minimum percentages for the PIP size logic.  */
-    private val mDefaultSizePercent: Float
-    private val mMinimumSizePercent: Float
+    /**
+     * Default percentages for the PIP size logic.
+     * 1. Determine max widths
+     * Subtract width of system UI and default padding from the shortest edge of the device.
+     * This is the max width.
+     * 2. Calculate Default and Mins
+     * Default is mSystemPreferredDefaultSizePercent of max-width/height.
+     * Min is mSystemPreferredMinimumSizePercent of it.
+     *
+     * NOTE: Do not use this directly, use the mPreferredDefaultSizePercent getter instead.
+     */
+    private var mSystemPreferredDefaultSizePercent = 0.6f
+    /** Minimum percentages for the PIP size logic. */
+    private var mSystemPreferredMinimumSizePercent = 0.5f
+
+    /** Threshold to categorize the Display as square, calculated as min(w, h) / max(w, h). */
+    private var mSquareDisplayThresholdForSystemPreferredSize = 0.95f
+    /**
+     * Default percentages for the PIP size logic when the Display is square-ish.
+     * This is used instead when the display is square-ish, like fold-ables when unfolded,
+     * to make sure that default PiP does not cover the hinge (halfway of the display).
+     * 1. Determine max widths
+     * Subtract width of system UI and default padding from the shortest edge of the device.
+     * This is the max width.
+     * 2. Calculate Default and Mins
+     * Default is mSystemPreferredDefaultSizePercent of max-width/height.
+     * Min is mSystemPreferredMinimumSizePercent of it.
+     *
+     * NOTE: Do not use this directly, use the mPreferredDefaultSizePercent getter instead.
+     */
+    private var mSystemPreferredDefaultSizePercentForSquareDisplay = 0.5f
+    /** Minimum percentages for the PIP size logic. */
+    private var mSystemPreferredMinimumSizePercentForSquareDisplay = 0.4f
+
+    private val mIsSquareDisplay
+        get() = minOf(pipDisplayLayoutState.displayLayout.width(),
+                        pipDisplayLayoutState.displayLayout.height()).toFloat() /
+                maxOf(pipDisplayLayoutState.displayLayout.width(),
+                        pipDisplayLayoutState.displayLayout.height()) >
+                mSquareDisplayThresholdForSystemPreferredSize
+    private val mPreferredDefaultSizePercent
+        get() = if (mIsSquareDisplay) mSystemPreferredDefaultSizePercentForSquareDisplay else
+            mSystemPreferredDefaultSizePercent
+
+    private val mPreferredMinimumSizePercent
+        get() = if (mIsSquareDisplay) mSystemPreferredMinimumSizePercentForSquareDisplay else
+            mSystemPreferredMinimumSizePercent
 
     /** Aspect ratio that the PIP size spec logic optimizes for.  */
     private var mOptimizedAspectRatio = 0f
 
     init {
-        mDefaultSizePercent = SystemProperties
-                .get("com.android.wm.shell.pip.phone.def_percentage", "0.6").toFloat()
-        mMinimumSizePercent = SystemProperties
-                .get("com.android.wm.shell.pip.phone.min_percentage", "0.5").toFloat()
-
         reloadResources()
     }
 
     private fun reloadResources() {
-        val res: Resources = context.getResources()
+        val res: Resources = context.resources
 
         mDefaultMinSize = res.getDimensionPixelSize(
                 R.dimen.default_minimal_size_pip_resizable_task)
         mOverridableMinSize = res.getDimensionPixelSize(
                 R.dimen.overridable_minimal_size_pip_resizable_task)
 
+        mSystemPreferredDefaultSizePercent = res.getFloat(
+                R.dimen.config_pipSystemPreferredDefaultSizePercent)
+        mSystemPreferredMinimumSizePercent = res.getFloat(
+                R.dimen.config_pipSystemPreferredMinimumSizePercent)
+
+        mSquareDisplayThresholdForSystemPreferredSize = res.getFloat(
+                R.dimen.config_pipSquareDisplayThresholdForSystemPreferredSize)
+        mSystemPreferredDefaultSizePercentForSquareDisplay = res.getFloat(
+                R.dimen.config_pipSystemPreferredDefaultSizePercentForSquareDisplay)
+        mSystemPreferredMinimumSizePercentForSquareDisplay = res.getFloat(
+                R.dimen.config_pipSystemPreferredMinimumSizePercentForSquareDisplay)
+
         val requestedOptAspRatio = res.getFloat(R.dimen.config_pipLargeScreenOptimizedAspectRatio)
         // make sure the optimized aspect ratio is valid with a default value to fall back to
         mOptimizedAspectRatio = if (requestedOptAspRatio > 1) {
@@ -128,7 +178,7 @@
             return minSize
         }
         val maxSize = getMaxSize(aspectRatio)
-        val defaultWidth = Math.max(Math.round(maxSize.width * mDefaultSizePercent),
+        val defaultWidth = Math.max(Math.round(maxSize.width * mPreferredDefaultSizePercent),
                 minSize.width)
         val defaultHeight = Math.round(defaultWidth / aspectRatio)
         return Size(defaultWidth, defaultHeight)
@@ -146,8 +196,8 @@
             return adjustOverrideMinSizeToAspectRatio(aspectRatio)!!
         }
         val maxSize = getMaxSize(aspectRatio)
-        var minWidth = Math.round(maxSize.width * mMinimumSizePercent)
-        var minHeight = Math.round(maxSize.height * mMinimumSizePercent)
+        var minWidth = Math.round(maxSize.width * mPreferredMinimumSizePercent)
+        var minHeight = Math.round(maxSize.height * mPreferredMinimumSizePercent)
 
         // make sure the calculated min size is not smaller than the allowed default min size
         if (aspectRatio > 1f) {
@@ -244,8 +294,8 @@
         pw.println(innerPrefix + "mOverrideMinSize=" + mOverrideMinSize)
         pw.println(innerPrefix + "mOverridableMinSize=" + mOverridableMinSize)
         pw.println(innerPrefix + "mDefaultMinSize=" + mDefaultMinSize)
-        pw.println(innerPrefix + "mDefaultSizePercent=" + mDefaultSizePercent)
-        pw.println(innerPrefix + "mMinimumSizePercent=" + mMinimumSizePercent)
+        pw.println(innerPrefix + "mDefaultSizePercent=" + mPreferredDefaultSizePercent)
+        pw.println(innerPrefix + "mMinimumSizePercent=" + mPreferredMinimumSizePercent)
         pw.println(innerPrefix + "mOptimizedAspectRatio=" + mOptimizedAspectRatio)
     }
 }
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhoneSizeSpecSourceTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhoneSizeSpecSourceTest.java
index 3d5cd69..85f1da5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhoneSizeSpecSourceTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhoneSizeSpecSourceTest.java
@@ -16,33 +16,26 @@
 
 package com.android.wm.shell.pip.phone;
 
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.res.Resources;
-import android.os.SystemProperties;
 import android.testing.AndroidTestingRunner;
 import android.util.Size;
 import android.view.DisplayInfo;
 
-import com.android.dx.mockito.inline.extended.StaticMockitoSession;
+import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.pip.PhoneSizeSpecSource;
 import com.android.wm.shell.common.pip.PipDisplayLayoutState;
 import com.android.wm.shell.common.pip.SizeSpecSource;
 
-import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.exceptions.misusing.InvalidUseOfMatchersException;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -63,15 +56,24 @@
     private static final float DEFAULT_PERCENT = 0.6f;
     /** Minimum sizing percentage */
     private static final float MIN_PERCENT = 0.5f;
+    /** Threshold to determine if a Display is square-ish. */
+    private static final float SQUARE_DISPLAY_THRESHOLD = 0.95f;
+    /** Default sizing percentage for square-ish Display. */
+    private static final float SQUARE_DISPLAY_DEFAULT_PERCENT = 0.5f;
+    /** Minimum sizing percentage for square-ish Display. */
+    private static final float SQUARE_DISPLAY_MIN_PERCENT = 0.4f;
     /** Aspect ratio that the new PIP size spec logic optimizes for. */
     private static final float OPTIMIZED_ASPECT_RATIO = 9f / 16;
 
-    /** A map of aspect ratios to be tested to expected sizes */
-    private static Map<Float, Size> sExpectedMaxSizes;
-    private static Map<Float, Size> sExpectedDefaultSizes;
-    private static Map<Float, Size> sExpectedMinSizes;
-    /** A static mockito session object to mock {@link SystemProperties} */
-    private static StaticMockitoSession sStaticMockitoSession;
+    /** Maps of aspect ratios to be tested to expected sizes on non-square Display. */
+    private static Map<Float, Size> sNonSquareDisplayExpectedMaxSizes;
+    private static Map<Float, Size> sNonSquareDisplayExpectedDefaultSizes;
+    private static Map<Float, Size> sNonSquareDisplayExpectedMinSizes;
+
+    /** Maps of aspect ratios to be tested to expected sizes on square Display. */
+    private static Map<Float, Size> sSquareDisplayExpectedMaxSizes;
+    private static Map<Float, Size> sSquareDisplayExpectedDefaultSizes;
+    private static Map<Float, Size> sSquareDisplayExpectedMinSizes;
 
     @Mock private Context mContext;
     @Mock private Resources mResources;
@@ -80,49 +82,55 @@
     private SizeSpecSource mSizeSpecSource;
 
     /**
-     * Sets up static Mockito session for SystemProperties and mocks necessary static methods.
+     * Initializes the map with the aspect ratios to be tested and corresponding expected max sizes.
+     * This is to initialize the expectations on non-square Display only.
      */
-    private static void setUpStaticSystemPropertiesSession() {
-        sStaticMockitoSession = mockitoSession()
-                .mockStatic(SystemProperties.class).startMocking();
-        when(SystemProperties.get(anyString(), anyString())).thenAnswer(invocation -> {
-            String property = invocation.getArgument(0);
-            if (property.equals("com.android.wm.shell.pip.phone.def_percentage")) {
-                return Float.toString(DEFAULT_PERCENT);
-            } else if (property.equals("com.android.wm.shell.pip.phone.min_percentage")) {
-                return Float.toString(MIN_PERCENT);
-            }
+    private static void initNonSquareDisplayExpectedSizes() {
+        sNonSquareDisplayExpectedMaxSizes = new HashMap<>();
+        sNonSquareDisplayExpectedDefaultSizes = new HashMap<>();
+        sNonSquareDisplayExpectedMinSizes = new HashMap<>();
 
-            // throw an exception if illegal arguments are used for these tests
-            throw new InvalidUseOfMatchersException(
-                String.format("Argument %s does not match", property)
-            );
-        });
+        sNonSquareDisplayExpectedMaxSizes.put(16f / 9, new Size(1000, 563));
+        sNonSquareDisplayExpectedDefaultSizes.put(16f / 9, new Size(600, 338));
+        sNonSquareDisplayExpectedMinSizes.put(16f / 9, new Size(501, 282));
+
+        sNonSquareDisplayExpectedMaxSizes.put(4f / 3, new Size(893, 670));
+        sNonSquareDisplayExpectedDefaultSizes.put(4f / 3, new Size(536, 402));
+        sNonSquareDisplayExpectedMinSizes.put(4f / 3, new Size(447, 335));
+
+        sNonSquareDisplayExpectedMaxSizes.put(3f / 4, new Size(670, 893));
+        sNonSquareDisplayExpectedDefaultSizes.put(3f / 4, new Size(402, 536));
+        sNonSquareDisplayExpectedMinSizes.put(3f / 4, new Size(335, 447));
+
+        sNonSquareDisplayExpectedMaxSizes.put(9f / 16, new Size(563, 1001));
+        sNonSquareDisplayExpectedDefaultSizes.put(9f / 16, new Size(338, 601));
+        sNonSquareDisplayExpectedMinSizes.put(9f / 16, new Size(282, 501));
     }
 
     /**
      * Initializes the map with the aspect ratios to be tested and corresponding expected max sizes.
+     * This is to initialize the expectations on square Display only.
      */
-    private static void initExpectedSizes() {
-        sExpectedMaxSizes = new HashMap<>();
-        sExpectedDefaultSizes = new HashMap<>();
-        sExpectedMinSizes = new HashMap<>();
+    private static void initSquareDisplayExpectedSizes() {
+        sSquareDisplayExpectedMaxSizes = new HashMap<>();
+        sSquareDisplayExpectedDefaultSizes = new HashMap<>();
+        sSquareDisplayExpectedMinSizes = new HashMap<>();
 
-        sExpectedMaxSizes.put(16f / 9, new Size(1000, 563));
-        sExpectedDefaultSizes.put(16f / 9, new Size(600, 338));
-        sExpectedMinSizes.put(16f / 9, new Size(501, 282));
+        sSquareDisplayExpectedMaxSizes.put(16f / 9, new Size(1000, 563));
+        sSquareDisplayExpectedDefaultSizes.put(16f / 9, new Size(500, 281));
+        sSquareDisplayExpectedMinSizes.put(16f / 9, new Size(400, 225));
 
-        sExpectedMaxSizes.put(4f / 3, new Size(893, 670));
-        sExpectedDefaultSizes.put(4f / 3, new Size(536, 402));
-        sExpectedMinSizes.put(4f / 3, new Size(447, 335));
+        sSquareDisplayExpectedMaxSizes.put(4f / 3, new Size(893, 670));
+        sSquareDisplayExpectedDefaultSizes.put(4f / 3, new Size(447, 335));
+        sSquareDisplayExpectedMinSizes.put(4f / 3, new Size(357, 268));
 
-        sExpectedMaxSizes.put(3f / 4, new Size(670, 893));
-        sExpectedDefaultSizes.put(3f / 4, new Size(402, 536));
-        sExpectedMinSizes.put(3f / 4, new Size(335, 447));
+        sSquareDisplayExpectedMaxSizes.put(3f / 4, new Size(670, 893));
+        sSquareDisplayExpectedDefaultSizes.put(3f / 4, new Size(335, 447));
+        sSquareDisplayExpectedMinSizes.put(3f / 4, new Size(268, 357));
 
-        sExpectedMaxSizes.put(9f / 16, new Size(563, 1001));
-        sExpectedDefaultSizes.put(9f / 16, new Size(338, 601));
-        sExpectedMinSizes.put(9f / 16, new Size(282, 501));
+        sSquareDisplayExpectedMaxSizes.put(9f / 16, new Size(563, 1001));
+        sSquareDisplayExpectedDefaultSizes.put(9f / 16, new Size(282, 501));
+        sSquareDisplayExpectedMinSizes.put(9f / 16, new Size(225, 400));
     }
 
     private void forEveryTestCaseCheck(Map<Float, Size> expectedSizes,
@@ -137,20 +145,38 @@
 
     @Before
     public void setUp() {
-        initExpectedSizes();
+        initNonSquareDisplayExpectedSizes();
+        initSquareDisplayExpectedSizes();
 
-        when(mResources.getDimensionPixelSize(anyInt())).thenReturn(DEFAULT_MIN_EDGE_SIZE);
-        when(mResources.getFloat(anyInt())).thenReturn(OPTIMIZED_ASPECT_RATIO);
-        when(mResources.getString(anyInt())).thenReturn("0x0");
+        when(mResources.getFloat(R.dimen.config_pipSystemPreferredDefaultSizePercent))
+                .thenReturn(DEFAULT_PERCENT);
+        when(mResources.getFloat(R.dimen.config_pipSystemPreferredMinimumSizePercent))
+                .thenReturn(MIN_PERCENT);
+        when(mResources.getDimensionPixelSize(R.dimen.default_minimal_size_pip_resizable_task))
+                .thenReturn(DEFAULT_MIN_EDGE_SIZE);
+        when(mResources.getFloat(R.dimen.config_pipLargeScreenOptimizedAspectRatio))
+                .thenReturn(OPTIMIZED_ASPECT_RATIO);
+        when(mResources.getString(R.string.config_defaultPictureInPictureScreenEdgeInsets))
+                .thenReturn("0x0");
         when(mResources.getDisplayMetrics())
                 .thenReturn(getContext().getResources().getDisplayMetrics());
+        when(mResources.getFloat(R.dimen.config_pipSquareDisplayThresholdForSystemPreferredSize))
+                .thenReturn(SQUARE_DISPLAY_THRESHOLD);
+        when(mResources.getFloat(
+                R.dimen.config_pipSystemPreferredDefaultSizePercentForSquareDisplay))
+                .thenReturn(SQUARE_DISPLAY_DEFAULT_PERCENT);
+        when(mResources.getFloat(
+                R.dimen.config_pipSystemPreferredMinimumSizePercentForSquareDisplay))
+                .thenReturn(SQUARE_DISPLAY_MIN_PERCENT);
 
         // set up the mock context for spec handler specifically
         when(mContext.getResources()).thenReturn(mResources);
+    }
 
+    private void setupSizeSpecWithDisplayDimension(int width, int height) {
         DisplayInfo displayInfo = new DisplayInfo();
-        displayInfo.logicalWidth = DISPLAY_EDGE_SIZE;
-        displayInfo.logicalHeight = DISPLAY_EDGE_SIZE;
+        displayInfo.logicalWidth = width;
+        displayInfo.logicalHeight = height;
 
         // use the parent context (not the mocked one) to obtain the display layout
         // this is done to avoid unnecessary mocking while allowing for custom display dimensions
@@ -159,38 +185,57 @@
         mPipDisplayLayoutState = new PipDisplayLayoutState(mContext);
         mPipDisplayLayoutState.setDisplayLayout(displayLayout);
 
-        setUpStaticSystemPropertiesSession();
         mSizeSpecSource = new PhoneSizeSpecSource(mContext, mPipDisplayLayoutState);
 
         // no overridden min edge size by default
         mSizeSpecSource.setOverrideMinSize(null);
     }
 
-    @After
-    public void cleanUp() {
-        sStaticMockitoSession.finishMocking();
-    }
-
     @Test
-    public void testGetMaxSize() {
-        forEveryTestCaseCheck(sExpectedMaxSizes,
+    public void testGetMaxSize_nonSquareDisplay() {
+        setupSizeSpecWithDisplayDimension(DISPLAY_EDGE_SIZE * 2, DISPLAY_EDGE_SIZE);
+        forEveryTestCaseCheck(sNonSquareDisplayExpectedMaxSizes,
                 (aspectRatio) -> mSizeSpecSource.getMaxSize(aspectRatio));
     }
 
     @Test
-    public void testGetDefaultSize() {
-        forEveryTestCaseCheck(sExpectedDefaultSizes,
+    public void testGetDefaultSize_nonSquareDisplay() {
+        setupSizeSpecWithDisplayDimension(DISPLAY_EDGE_SIZE * 2, DISPLAY_EDGE_SIZE);
+        forEveryTestCaseCheck(sNonSquareDisplayExpectedDefaultSizes,
                 (aspectRatio) -> mSizeSpecSource.getDefaultSize(aspectRatio));
     }
 
     @Test
-    public void testGetMinSize() {
-        forEveryTestCaseCheck(sExpectedMinSizes,
+    public void testGetMinSize_nonSquareDisplay() {
+        setupSizeSpecWithDisplayDimension(DISPLAY_EDGE_SIZE * 2, DISPLAY_EDGE_SIZE);
+        forEveryTestCaseCheck(sNonSquareDisplayExpectedMinSizes,
+                (aspectRatio) -> mSizeSpecSource.getMinSize(aspectRatio));
+    }
+
+    @Test
+    public void testGetMaxSize_squareDisplay() {
+        setupSizeSpecWithDisplayDimension(DISPLAY_EDGE_SIZE, DISPLAY_EDGE_SIZE);
+        forEveryTestCaseCheck(sSquareDisplayExpectedMaxSizes,
+                (aspectRatio) -> mSizeSpecSource.getMaxSize(aspectRatio));
+    }
+
+    @Test
+    public void testGetDefaultSize_squareDisplay() {
+        setupSizeSpecWithDisplayDimension(DISPLAY_EDGE_SIZE, DISPLAY_EDGE_SIZE);
+        forEveryTestCaseCheck(sSquareDisplayExpectedDefaultSizes,
+                (aspectRatio) -> mSizeSpecSource.getDefaultSize(aspectRatio));
+    }
+
+    @Test
+    public void testGetMinSize_squareDisplay() {
+        setupSizeSpecWithDisplayDimension(DISPLAY_EDGE_SIZE, DISPLAY_EDGE_SIZE);
+        forEveryTestCaseCheck(sSquareDisplayExpectedMinSizes,
                 (aspectRatio) -> mSizeSpecSource.getMinSize(aspectRatio));
     }
 
     @Test
     public void testGetSizeForAspectRatio_noOverrideMinSize() {
+        setupSizeSpecWithDisplayDimension(DISPLAY_EDGE_SIZE * 2, DISPLAY_EDGE_SIZE);
         // an initial size with 16:9 aspect ratio
         Size initSize = new Size(600, 337);
 
@@ -202,6 +247,7 @@
 
     @Test
     public void testGetSizeForAspectRatio_withOverrideMinSize() {
+        setupSizeSpecWithDisplayDimension(DISPLAY_EDGE_SIZE * 2, DISPLAY_EDGE_SIZE);
         // an initial size with a 1:1 aspect ratio
         Size initSize = new Size(OVERRIDE_MIN_EDGE_SIZE, OVERRIDE_MIN_EDGE_SIZE);
         mSizeSpecSource.setOverrideMinSize(initSize);
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index f1eea72..df84653 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -1839,18 +1839,19 @@
                                     && !mBtHelper.isProfilePoxyConnected(btInfo.mProfile)) {
                                 AudioService.sDeviceLogger.enqueue((new EventLogger.StringEvent(
                                         "msg: MSG_L_SET_BT_ACTIVE_DEVICE "
-                                            + "received with null profile proxy: "
-                                            + btInfo)).printLog(TAG));
+                                                + "received with null profile proxy: "
+                                                + btInfo)).printLog(TAG));
                             } else {
-                                @AudioSystem.AudioFormatNativeEnumForBtCodec final int codec =
+                                final Pair<Integer, Boolean> codecAndChanged =
                                         mBtHelper.getCodecWithFallback(btInfo.mDevice,
                                                 btInfo.mProfile, btInfo.mIsLeOutput,
                                                 "MSG_L_SET_BT_ACTIVE_DEVICE");
-                                mDeviceInventory.onSetBtActiveDevice(btInfo, codec,
-                                        (btInfo.mProfile
-                                                != BluetoothProfile.LE_AUDIO || btInfo.mIsLeOutput)
-                                                ? mAudioService.getBluetoothContextualVolumeStream()
-                                                : AudioSystem.STREAM_DEFAULT);
+                                mDeviceInventory.onSetBtActiveDevice(btInfo,
+                                        codecAndChanged.first,
+                                        (btInfo.mProfile != BluetoothProfile.LE_AUDIO
+                                                || btInfo.mIsLeOutput)
+                                            ? mAudioService.getBluetoothContextualVolumeStream()
+                                            : AudioSystem.STREAM_DEFAULT);
                                 if (btInfo.mProfile == BluetoothProfile.LE_AUDIO
                                         || btInfo.mProfile == BluetoothProfile.HEARING_AID) {
                                     onUpdateCommunicationRouteClient(isBluetoothScoRequested(),
@@ -1884,12 +1885,13 @@
                 case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE: {
                     final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj;
                     synchronized (mDeviceStateLock) {
-                        @AudioSystem.AudioFormatNativeEnumForBtCodec final int codec =
-                                mBtHelper.getCodecWithFallback(btInfo.mDevice,
-                                        btInfo.mProfile, btInfo.mIsLeOutput,
-                                        "MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE");
-                        mDeviceInventory.onBluetoothDeviceConfigChange(
-                                btInfo, codec, BtHelper.EVENT_DEVICE_CONFIG_CHANGE);
+                        final Pair<Integer, Boolean> codecAndChanged =
+                                mBtHelper.getCodecWithFallback(
+                                    btInfo.mDevice, btInfo.mProfile, btInfo.mIsLeOutput,
+                                    "MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE");
+                        mDeviceInventory.onBluetoothDeviceConfigChange(btInfo,
+                                codecAndChanged.first, codecAndChanged.second,
+                                BtHelper.EVENT_DEVICE_CONFIG_CHANGE);
                     }
                 } break;
                 case MSG_BROADCAST_AUDIO_BECOMING_NOISY:
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index e0c2425..8b64d93 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -864,7 +864,8 @@
     @GuardedBy("mDeviceBroker.mDeviceStateLock")
     /*package*/ void onBluetoothDeviceConfigChange(
             @NonNull AudioDeviceBroker.BtDeviceInfo btInfo,
-            @AudioSystem.AudioFormatNativeEnumForBtCodec int codec, int event) {
+            @AudioSystem.AudioFormatNativeEnumForBtCodec int codec,
+            boolean codecChanged, int event) {
         MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId
                 + "onBluetoothDeviceConfigChange")
                 .set(MediaMetrics.Property.EVENT, BtHelper.deviceEventToString(event));
@@ -912,14 +913,12 @@
 
 
             if (event == BtHelper.EVENT_DEVICE_CONFIG_CHANGE) {
-                boolean codecChange = false;
                 if (btInfo.mProfile == BluetoothProfile.A2DP
                         || btInfo.mProfile == BluetoothProfile.LE_AUDIO
                         || btInfo.mProfile == BluetoothProfile.LE_AUDIO_BROADCAST) {
-                    if (di.mDeviceCodecFormat != codec) {
+                    if (codecChanged) {
                         di.mDeviceCodecFormat = codec;
                         mConnectedDevices.replace(key, di);
-                        codecChange = true;
                         final int res = mAudioSystem.handleDeviceConfigChange(
                                 btInfo.mAudioSystemDevice, address,
                                 BtHelper.getName(btDevice), codec);
@@ -943,7 +942,7 @@
                         }
                     }
                 }
-                if (!codecChange) {
+                if (!codecChanged) {
                     updateBluetoothPreferredModes_l(btDevice /*connectedDevice*/);
                 }
             }
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 0f3f807..69f7399 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -98,9 +98,16 @@
 
     private @Nullable BluetoothLeAudio mLeAudio;
 
+    private @Nullable BluetoothLeAudioCodecConfig mLeAudioCodecConfig;
+
     // Reference to BluetoothA2dp to query for AbsoluteVolume.
     private @Nullable BluetoothA2dp mA2dp;
 
+    private @Nullable BluetoothCodecConfig mA2dpCodecConfig;
+
+    private @AudioSystem.AudioFormatNativeEnumForBtCodec
+            int mLeAudioBroadcastCodec = AudioSystem.AUDIO_FORMAT_DEFAULT;
+
     // If absolute volume is supported in AVRCP device
     private boolean mAvrcpAbsVolSupported = false;
 
@@ -269,12 +276,15 @@
         }
     }
 
-    /*package*/ synchronized @AudioSystem.AudioFormatNativeEnumForBtCodec int getCodec(
+    private synchronized Pair<Integer, Boolean> getCodec(
             @NonNull BluetoothDevice device, @AudioService.BtProfile int profile) {
+
         switch (profile) {
             case BluetoothProfile.A2DP: {
+                boolean changed = mA2dpCodecConfig != null;
                 if (mA2dp == null) {
-                    return AudioSystem.AUDIO_FORMAT_DEFAULT;
+                    mA2dpCodecConfig = null;
+                    return new Pair<>(AudioSystem.AUDIO_FORMAT_DEFAULT, changed);
                 }
                 BluetoothCodecStatus btCodecStatus = null;
                 try {
@@ -283,17 +293,24 @@
                     Log.e(TAG, "Exception while getting status of " + device, e);
                 }
                 if (btCodecStatus == null) {
-                    return AudioSystem.AUDIO_FORMAT_DEFAULT;
+                    mA2dpCodecConfig = null;
+                    return new Pair<>(AudioSystem.AUDIO_FORMAT_DEFAULT, changed);
                 }
                 final BluetoothCodecConfig btCodecConfig = btCodecStatus.getCodecConfig();
                 if (btCodecConfig == null) {
-                    return AudioSystem.AUDIO_FORMAT_DEFAULT;
+                    mA2dpCodecConfig = null;
+                    return new Pair<>(AudioSystem.AUDIO_FORMAT_DEFAULT, changed);
                 }
-                return AudioSystem.bluetoothA2dpCodecToAudioFormat(btCodecConfig.getCodecType());
+                changed = !btCodecConfig.equals(mA2dpCodecConfig);
+                mA2dpCodecConfig = btCodecConfig;
+                return new Pair<>(AudioSystem.bluetoothA2dpCodecToAudioFormat(
+                        btCodecConfig.getCodecType()), changed);
             }
             case BluetoothProfile.LE_AUDIO: {
+                boolean changed = mLeAudioCodecConfig != null;
                 if (mLeAudio == null) {
-                    return AudioSystem.AUDIO_FORMAT_DEFAULT;
+                    mLeAudioCodecConfig = null;
+                    return new Pair<>(AudioSystem.AUDIO_FORMAT_DEFAULT, changed);
                 }
                 BluetoothLeAudioCodecStatus btLeCodecStatus = null;
                 int groupId = mLeAudio.getGroupId(device);
@@ -303,42 +320,54 @@
                     Log.e(TAG, "Exception while getting status of " + device, e);
                 }
                 if (btLeCodecStatus == null) {
-                    return AudioSystem.AUDIO_FORMAT_DEFAULT;
+                    mLeAudioCodecConfig = null;
+                    return new Pair<>(AudioSystem.AUDIO_FORMAT_DEFAULT, changed);
                 }
                 BluetoothLeAudioCodecConfig btLeCodecConfig =
                         btLeCodecStatus.getOutputCodecConfig();
                 if (btLeCodecConfig == null) {
-                    return AudioSystem.AUDIO_FORMAT_DEFAULT;
+                    mLeAudioCodecConfig = null;
+                    return new Pair<>(AudioSystem.AUDIO_FORMAT_DEFAULT, changed);
                 }
-                return AudioSystem.bluetoothLeCodecToAudioFormat(btLeCodecConfig.getCodecType());
+                changed = !btLeCodecConfig.equals(mLeAudioCodecConfig);
+                mLeAudioCodecConfig = btLeCodecConfig;
+                return new Pair<>(AudioSystem.bluetoothLeCodecToAudioFormat(
+                        btLeCodecConfig.getCodecType()), changed);
+            }
+            case BluetoothProfile.LE_AUDIO_BROADCAST: {
+                // We assume LC3 for LE Audio broadcast codec as there is no API to get the codec
+                // config on LE Broadcast profile proxy.
+                boolean changed = mLeAudioBroadcastCodec != AudioSystem.AUDIO_FORMAT_LC3;
+                mLeAudioBroadcastCodec = AudioSystem.AUDIO_FORMAT_LC3;
+                return new Pair<>(mLeAudioBroadcastCodec, changed);
             }
             default:
-                return AudioSystem.AUDIO_FORMAT_DEFAULT;
+                return new Pair<>(AudioSystem.AUDIO_FORMAT_DEFAULT, false);
         }
     }
 
-    /*package*/ synchronized @AudioSystem.AudioFormatNativeEnumForBtCodec
-            int getCodecWithFallback(
-                    @NonNull BluetoothDevice device, @AudioService.BtProfile int profile,
-                    boolean isLeOutput, @NonNull String source) {
+    /*package*/ synchronized Pair<Integer, Boolean>
+                    getCodecWithFallback(@NonNull BluetoothDevice device,
+                                         @AudioService.BtProfile int profile,
+                                         boolean isLeOutput, @NonNull String source) {
         // For profiles other than A2DP and LE Audio output, the audio codec format must be
         // AUDIO_FORMAT_DEFAULT as native audio policy manager expects a specific audio format
         // only if audio HW module selection based on format is supported for the device type.
         if (!(profile == BluetoothProfile.A2DP
                 || (isLeOutput && ((profile == BluetoothProfile.LE_AUDIO)
                         || (profile == BluetoothProfile.LE_AUDIO_BROADCAST))))) {
-            return AudioSystem.AUDIO_FORMAT_DEFAULT;
+            return new Pair<>(AudioSystem.AUDIO_FORMAT_DEFAULT, false);
         }
-        @AudioSystem.AudioFormatNativeEnumForBtCodec int codec =
+        Pair<Integer, Boolean> codecAndChanged =
                 getCodec(device, profile);
-        if (codec == AudioSystem.AUDIO_FORMAT_DEFAULT) {
+        if (codecAndChanged.first == AudioSystem.AUDIO_FORMAT_DEFAULT) {
             AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
                     "getCodec DEFAULT from " + source + " fallback to "
                             + (profile == BluetoothProfile.A2DP ? "SBC" : "LC3")));
-            return profile == BluetoothProfile.A2DP
-                    ? AudioSystem.AUDIO_FORMAT_SBC : AudioSystem.AUDIO_FORMAT_LC3;
+            return new Pair<>(profile == BluetoothProfile.A2DP
+                    ? AudioSystem.AUDIO_FORMAT_SBC : AudioSystem.AUDIO_FORMAT_LC3, true);
         }
-        return codec;
+        return codecAndChanged;
     }
 
     // @GuardedBy("mDeviceBroker.mSetModeLock")
@@ -543,15 +572,19 @@
                 break;
             case BluetoothProfile.A2DP:
                 mA2dp = null;
+                mA2dpCodecConfig = null;
                 break;
             case BluetoothProfile.HEARING_AID:
                 mHearingAid = null;
                 break;
             case BluetoothProfile.LE_AUDIO:
                 mLeAudio = null;
+                mLeAudioCodecConfig = null;
+                break;
+            case BluetoothProfile.LE_AUDIO_BROADCAST:
+                mLeAudioBroadcastCodec = AudioSystem.AUDIO_FORMAT_DEFAULT;
                 break;
             case BluetoothProfile.A2DP_SINK:
-            case BluetoothProfile.LE_AUDIO_BROADCAST:
                 // nothing to do in BtHelper
                 break;
             default:
diff --git a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
index a63db88..7b5b07c 100644
--- a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
+++ b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
@@ -16,6 +16,8 @@
 package com.android.internal.telephony.util;
 
 import static android.telephony.Annotation.DataState;
+import static android.telephony.NetworkRegistrationInfo.FIRST_SERVICE_TYPE;
+import static android.telephony.NetworkRegistrationInfo.LAST_SERVICE_TYPE;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -37,6 +39,7 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyFrameworkInitializer;
 import android.telephony.TelephonyManager;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.internal.telephony.ITelephony;
@@ -48,6 +51,8 @@
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Supplier;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * This class provides various util functions
@@ -342,4 +347,31 @@
         return false;
 
     }
+
+    /**
+     * @param plmn target plmn for validation.
+     * @return {@code true} if the target plmn is valid {@code false} otherwise.
+     */
+    public static boolean isValidPlmn(@Nullable String plmn) {
+        if (TextUtils.isEmpty(plmn)) {
+            return false;
+        }
+        Pattern pattern = Pattern.compile("^(?:[0-9]{3})(?:[0-9]{2}|[0-9]{3})$");
+        Matcher matcher = pattern.matcher(plmn);
+        if (!matcher.matches()) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * @param serviceType target serviceType for validation.
+     * @return {@code true} if the target serviceType is valid {@code false} otherwise.
+     */
+    public static boolean isValidService(int serviceType) {
+        if (serviceType < FIRST_SERVICE_TYPE || serviceType > LAST_SERVICE_TYPE) {
+            return false;
+        }
+        return true;
+    }
 }
diff --git a/telephony/java/android/telephony/satellite/stub/ISatellite.aidl b/telephony/java/android/telephony/satellite/stub/ISatellite.aidl
index 36485c6..16983a0 100644
--- a/telephony/java/android/telephony/satellite/stub/ISatellite.aidl
+++ b/telephony/java/android/telephony/satellite/stub/ISatellite.aidl
@@ -83,6 +83,9 @@
      *
      * @param enableSatellite True to enable the satellite modem and false to disable.
      * @param enableDemoMode True to enable demo mode and false to disable.
+     * @param isEmergency To specify the satellite is enabled for emergency session and false for
+     * non emergency session. Note: it is possible that a emergency session started get converted
+     * to a non emergency session and vice versa.
      * @param resultCallback The callback to receive the error code result of the operation.
      *
      * Valid result codes returned:
@@ -96,7 +99,7 @@
      *   SatelliteResult:SATELLITE_RESULT_NO_RESOURCES
      */
     void requestSatelliteEnabled(in boolean enableSatellite, in boolean enableDemoMode,
-            in IIntegerConsumer resultCallback);
+            in boolean isEmergency, in IIntegerConsumer resultCallback);
 
     /**
      * Request to get whether the satellite modem is enabled.
diff --git a/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java b/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java
index b7dc79f..a623633 100644
--- a/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java
+++ b/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java
@@ -90,11 +90,11 @@
 
         @Override
         public void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode,
-                IIntegerConsumer resultCallback) throws RemoteException {
+                boolean isEmergency, IIntegerConsumer resultCallback) throws RemoteException {
             executeMethodAsync(
                     () -> SatelliteImplBase.this
                             .requestSatelliteEnabled(
-                                    enableSatellite, enableDemoMode, resultCallback),
+                                    enableSatellite, enableDemoMode, isEmergency, resultCallback),
                     "requestSatelliteEnabled");
         }
 
@@ -337,6 +337,9 @@
      *
      * @param enableSatellite True to enable the satellite modem and false to disable.
      * @param enableDemoMode True to enable demo mode and false to disable.
+     * @param isEmergency To specify the satellite is enabled for emergency session and false for
+     * non emergency session. Note: it is possible that a emergency session started get converted
+     * to a non emergency session and vice versa.
      * @param resultCallback The callback to receive the error code result of the operation.
      *
      * Valid result codes returned:
@@ -350,7 +353,7 @@
      *   SatelliteResult:SATELLITE_RESULT_NO_RESOURCES
      */
     public void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode,
-            @NonNull IIntegerConsumer resultCallback) {
+            boolean isEmergency, @NonNull IIntegerConsumer resultCallback) {
         // stub implementation
     }
 
diff --git a/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/TelephonyUtilsTest.java b/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/TelephonyUtilsTest.java
index a62103e..7558332 100644
--- a/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/TelephonyUtilsTest.java
+++ b/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/TelephonyUtilsTest.java
@@ -16,10 +16,16 @@
 
 package com.android.internal.telephony.tests;
 
+import static android.telephony.NetworkRegistrationInfo.FIRST_SERVICE_TYPE;
+import static android.telephony.NetworkRegistrationInfo.LAST_SERVICE_TYPE;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.content.Context;
@@ -72,6 +78,22 @@
         // getSubscriptionUserHandle should be called if subID is active.
         verify(mSubscriptionManager, times(1)).getSubscriptionUserHandle(eq(activeSubId));
     }
+
+    @Test
+    public void testIsValidPlmn() {
+        assertTrue(TelephonyUtils.isValidPlmn("310260"));
+        assertTrue(TelephonyUtils.isValidPlmn("45006"));
+        assertFalse(TelephonyUtils.isValidPlmn("1234567"));
+        assertFalse(TelephonyUtils.isValidPlmn("1234"));
+    }
+
+    @Test
+    public void testIsValidService() {
+        assertTrue(TelephonyUtils.isValidService(FIRST_SERVICE_TYPE));
+        assertTrue(TelephonyUtils.isValidService(LAST_SERVICE_TYPE));
+        assertFalse(TelephonyUtils.isValidService(FIRST_SERVICE_TYPE - 1));
+        assertFalse(TelephonyUtils.isValidService(LAST_SERVICE_TYPE + 1));
+    }
 }