Merge "Fix RTL layout" into udc-dev
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 8849a77..3971dbd 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -180,7 +180,6 @@
 import com.android.internal.telephony.ICallForwardingInfoCallback;
 import com.android.internal.telephony.IImsStateCallback;
 import com.android.internal.telephony.IIntegerConsumer;
-import com.android.internal.telephony.ILongConsumer;
 import com.android.internal.telephony.INumberVerificationCallback;
 import com.android.internal.telephony.ITelephony;
 import com.android.internal.telephony.IccCard;
@@ -3038,11 +3037,12 @@
                 + ",reason=" + reason + ",callingPackage=" + getCurrentPackageName());
         final long identity = Binder.clearCallingIdentity();
         try {
-            final Phone phone = getPhone(subId);
+            final Phone phone = getPhoneFromSubIdOrDefault(subId);
             if (phone != null) {
                 phone.setRadioPowerForReason(false, reason);
                 return true;
             } else {
+                loge("requestRadioPowerOffForReason: phone is null");
                 return false;
             }
         } finally {
@@ -3064,11 +3064,12 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            final Phone phone = getPhone(subId);
+            final Phone phone = getPhoneFromSubIdOrDefault(subId);
             if (phone != null) {
                 phone.setRadioPowerForReason(true, reason);
                 return true;
             } else {
+                loge("clearRadioPowerOffForReason: phone is null");
                 return false;
             }
         } finally {
@@ -3095,9 +3096,11 @@
                 return result;
             }
 
-            final Phone phone = getPhone(subId);
+            final Phone phone = getPhoneFromSubIdOrDefault(subId);
             if (phone != null) {
                 result.addAll(phone.getRadioPowerOffReasons());
+            } else {
+                loge("getRadioPowerOffReasons: phone is null");
             }
         } finally {
             Binder.restoreCallingIdentity(identity);
@@ -12513,6 +12516,24 @@
     }
 
     /**
+     * This API can be used by only CTS to update the timeout duration in milliseconds that
+     * satellite should stay at listening mode to wait for the next incoming page before disabling
+     * listening mode.
+     *
+     * @param timeoutMillis The timeout duration in millisecond.
+     * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
+     */
+    public boolean setSatelliteListeningTimeoutDuration(long timeoutMillis) {
+        Log.d(LOG_TAG, "setSatelliteListeningTimeoutDuration - " + timeoutMillis);
+        TelephonyPermissions.enforceShellOnly(
+                Binder.getCallingUid(), "setSatelliteListeningTimeoutDuration");
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                "setSatelliteListeningTimeoutDuration");
+        return mSatelliteController.setSatelliteListeningTimeoutDuration(timeoutMillis);
+    }
+
+    /**
      * Check whether the caller (or self, if not processing an IPC) can read device identifiers.
      *
      * <p>This method behaves in one of the following ways:
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index 53c7f4e..80df099 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -181,6 +181,8 @@
     private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
     private static final String SET_SATELLITE_SERVICE_PACKAGE_NAME =
             "set-satellite-service-package-name";
+    private static final String SET_SATELLITE_LISTENING_TIMEOUT_DURATION =
+            "set-satellite-listening-timeout-duration";
 
     private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', "
             + "'*', '#' or '+') needs to be specified after -a in the command ";
@@ -364,6 +366,8 @@
                 return clearCarrierServicePackageOverride();
             case SET_SATELLITE_SERVICE_PACKAGE_NAME:
                 return handleSetSatelliteServicePackageNameCommand();
+            case SET_SATELLITE_LISTENING_TIMEOUT_DURATION:
+                return handleSetSatelliteListeningTimeoutDuration();
             default: {
                 return handleDefaultCommands(cmd);
             }
@@ -743,9 +747,14 @@
         pw.println("Satellite Commands:");
         pw.println("  set-satellite-service-package-name [-s SERVICE_PACKAGE_NAME]");
         pw.println("    Sets the package name of satellite service defined in");
-        pw.println("    SERVICE_PACKAGE_NAME to be the bound. Options are:");
+        pw.println("    SERVICE_PACKAGE_NAME to be bound. Options are:");
         pw.println("      -s: the satellite service package name that Telephony will bind to.");
         pw.println("          If no option is specified, it will bind to the default.");
+        pw.println("  set-satellite-listening-timeout-duration [-t TIMEOUT_MILLIS]");
+        pw.println("    Sets the timeout duration in millis that satellite will stay at listening");
+        pw.println("    mode. Options are:");
+        pw.println("      -t: the timeout duration in milliseconds.");
+        pw.println("          If no option is specified, it will use the default values.");
     }
 
     private void onHelpImei() {
@@ -3116,6 +3125,38 @@
         return 0;
     }
 
+    private int handleSetSatelliteListeningTimeoutDuration() {
+        PrintWriter errPw = getErrPrintWriter();
+        long timeoutMillis = 0;
+
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            switch (opt) {
+                case "-t": {
+                    timeoutMillis = Long.parseLong(getNextArgRequired());
+                    break;
+                }
+            }
+        }
+        Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis="
+                + timeoutMillis);
+
+        try {
+            boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis);
+            if (VDBG) {
+                Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis
+                        + ", result = " + result);
+            }
+            getOutPrintWriter().println(result);
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis
+                    + ", error = " + e.getMessage());
+            errPw.println("Exception: " + e.getMessage());
+            return -1;
+        }
+        return 0;
+    }
+
     private int handleCarrierRestrictionStatusCommand() {
         try {
             String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 9f248b7..6d136b0 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -331,7 +331,6 @@
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
                         sendTelephonyConnectionEvent((String) args.arg1, (Bundle) args.arg2);
-
                     } finally {
                         args.recycle();
                     }
@@ -738,7 +737,13 @@
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = event;
             args.arg2 = extras;
-            mHandler.obtainMessage(MSG_ON_CONNECTION_EVENT, args).sendToTarget();
+            if (EVENT_MERGE_COMPLETE.equals(event)){
+                // To ensure the MERGE_COMPLETE event logs before the listeners are removed,
+                // circumvent the handler by sending the connection event directly:
+                sendTelephonyConnectionEvent(event, extras);
+            } else {
+                mHandler.obtainMessage(MSG_ON_CONNECTION_EVENT, args).sendToTarget();
+            }
         }
 
         @Override
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 1852ed7..7c30bff 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -553,7 +553,11 @@
                 @Override
                 public void onOriginalConnectionConfigured(TelephonyConnection c) {
                     com.android.internal.telephony.Connection origConn = c.getOriginalConnection();
-                    if (origConn == null) return;
+                    if ((origConn == null) || (mEmergencyStateTracker == null)) {
+                        // mEmergencyStateTracker is null when no emergency call has been dialed
+                        // after bootup and normal call fails with 380 response.
+                        return;
+                    }
                     // Update the domain in the case that it changes,for example during initial
                     // setup or when there was an srvcc or internal redial.
                     mEmergencyStateTracker.onEmergencyCallDomainUpdated(
diff --git a/testapps/TestSliceApp/app/src/main/AndroidManifest.xml b/testapps/TestSliceApp/app/src/main/AndroidManifest.xml
index 53754de..cea9e5f 100644
--- a/testapps/TestSliceApp/app/src/main/AndroidManifest.xml
+++ b/testapps/TestSliceApp/app/src/main/AndroidManifest.xml
@@ -32,5 +32,7 @@
       <meta-data android:name="android.service.carrier.LONG_LIVED_BINDING"
           android:value="true" />
     </service>
+    <property android:name="android.net.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES"
+              android:resource="@xml/self_certified_network_capabilities_both" />
   </application>
 </manifest>
diff --git a/testapps/TestSliceApp/app/src/main/res/xml/self_certified_network_capabilities_both.xml b/testapps/TestSliceApp/app/src/main/res/xml/self_certified_network_capabilities_both.xml
new file mode 100644
index 0000000..cd4d370
--- /dev/null
+++ b/testapps/TestSliceApp/app/src/main/res/xml/self_certified_network_capabilities_both.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<network-capabilities-declaration xmlns:android="http://schemas.android.com/apk/res/android">
+    <uses-network-capability android:name="NET_CAPABILITY_PRIORITIZE_LATENCY"/>
+    <uses-network-capability android:name="NET_CAPABILITY_PRIORITIZE_BANDWIDTH"/>
+</network-capabilities-declaration>
\ No newline at end of file