Merge "Add @UnsupportedAppUsage annotations for greylist." am: be1393d695
am: c5178397df

Change-Id: I9f884f482e4622b3588488a97662f7e205fca9c3
diff --git a/proto/src/telephony.proto b/proto/src/telephony.proto
index e9a564e..ec2acf4 100644
--- a/proto/src/telephony.proto
+++ b/proto/src/telephony.proto
@@ -331,6 +331,10 @@
   RAT_IWLAN = 18;
 
   RAT_LTE_CA = 19;
+
+  RAT_NR_NSA = 20;
+
+  RAT_NR_SA = 21;
 }
 
 // The information about IMS errors
diff --git a/src/java/com/android/internal/telephony/CellBroadcastHandler.java b/src/java/com/android/internal/telephony/CellBroadcastHandler.java
index 87ecdc0..d89f45c 100644
--- a/src/java/com/android/internal/telephony/CellBroadcastHandler.java
+++ b/src/java/com/android/internal/telephony/CellBroadcastHandler.java
@@ -397,8 +397,8 @@
         }
 
         private boolean hasPermission(String permission) {
-            return PermissionChecker.checkCallingOrSelfPermissionForDataDelivery(mContext, permission)
-                    == PERMISSION_GRANTED;
+            return PermissionChecker.checkCallingOrSelfPermissionForDataDelivery(mContext,
+                    permission) == PERMISSION_GRANTED;
         }
 
         private final LocationListener mLocationListener = new LocationListener() {
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index 150b29b..dc7d19c 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -36,6 +36,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.IPackageManager;
+import android.content.pm.UserInfo;
 import android.database.Cursor;
 import android.database.SQLException;
 import android.net.Uri;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 1ed0d6a..ec3f324 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -99,13 +99,13 @@
 import com.android.internal.telephony.LocaleTracker;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.PhoneInternalInterface;
 import com.android.internal.telephony.ServiceStateTracker;
 import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.telephony.dataconnection.DataEnabledSettings;
 import com.android.internal.telephony.dataconnection.DataEnabledSettings.DataEnabledChangedReason;
 import com.android.internal.telephony.gsm.SuppServiceNotification;
+import com.android.internal.telephony.imsphone.ImsPhone.ImsDialArgs;
 import com.android.internal.telephony.metrics.CallQualityMetrics;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.nano.TelephonyProto.ImsConnectionState;
@@ -319,6 +319,7 @@
     private static final int EVENT_REDIAL_WIFI_E911_TIMEOUT = 29;
     private static final int EVENT_ANSWER_WAITING_CALL = 30;
     private static final int EVENT_RESUME_NOW_FOREGROUND_CALL = 31;
+    private static final int EVENT_REDIAL_WITHOUT_RTT = 32;
 
     private static final int TIMEOUT_HANGUP_PENDINGMO = 500;
 
@@ -442,7 +443,8 @@
     private HoldSwapState mHoldSwitchingState = HoldSwapState.INACTIVE;
 
     private String mLastDialString = null;
-    private PhoneInternalInterface.DialArgs mLastDialArgs = null;
+    private ImsDialArgs mLastDialArgs = null;
+
     /**
      * Listeners to changes in the phone state.  Intended for use by other interested IMS components
      * without the need to register a full blown {@link android.telephony.PhoneStateListener}.
@@ -2458,6 +2460,10 @@
                         .getSystemService(Context.CONNECTIVITY_SERVICE);
                 mgr.setAirplaneMode(false);
                 return;
+            } else if (reasonInfo.getCode() == ImsReasonInfo.CODE_RETRY_ON_IMS_WITHOUT_RTT) {
+                Pair<ImsCall, ImsReasonInfo> callInfo = new Pair<>(imsCall, reasonInfo);
+                sendMessage(obtainMessage(EVENT_REDIAL_WITHOUT_RTT, callInfo));
+                return;
             } else {
                 processCallStateChange(imsCall, ImsPhoneCall.State.DISCONNECTED, cause);
             }
@@ -3518,6 +3524,30 @@
                 sendCallStartFailedDisconnect(callInfo.first, callInfo.second);
                 break;
             }
+
+            case EVENT_REDIAL_WITHOUT_RTT: {
+                Pair<ImsCall, ImsReasonInfo> callInfo = (Pair<ImsCall, ImsReasonInfo>) msg.obj;
+                removeMessages(EVENT_REDIAL_WITHOUT_RTT);
+                ImsPhoneConnection oldConnection = findConnection(callInfo.first);
+                if (oldConnection == null) {
+                    sendCallStartFailedDisconnect(callInfo.first, callInfo.second);
+                    break;
+                }
+                mForegroundCall.detach(oldConnection);
+                removeConnection(oldConnection);
+                try {
+                    mPendingMO = null;
+                    ImsDialArgs newDialArgs = ImsDialArgs.Builder.from(mLastDialArgs)
+                            .setRttTextStream(null)
+                            .build();
+                    Connection newConnection =
+                            mPhone.getDefaultPhone().dial(mLastDialString, newDialArgs);
+                    oldConnection.onOriginalConnectionReplaced(newConnection);
+                } catch (CallStateException e) {
+                    sendCallStartFailedDisconnect(callInfo.first, callInfo.second);
+                }
+                break;
+            }
         }
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
index f2d4a17..08defe3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
@@ -32,8 +32,11 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.IBinder;
+import android.os.ServiceManager;
 import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.telephony.SubscriptionManager;
@@ -50,14 +53,15 @@
 import org.mockito.MockitoAnnotations;
 
 import java.lang.reflect.Field;
+import java.util.Map;
 
 @SmallTest
 public class TelephonyPermissionsTest {
 
     private static final int SUB_ID = 55555;
     private static final int SUB_ID_2 = 22222;
-    private static final int PID = 12345;
-    private static final int UID = 54321;
+    private static final int PID = Binder.getCallingPid();
+    private static final int UID = Binder.getCallingUid();
     private static final String PACKAGE = "com.example";
     private static final String MSG = "message";
 
@@ -70,6 +74,8 @@
     @Mock
     private ITelephony mMockTelephony;
     @Mock
+    private IBinder mMockTelephonyBinder;
+    @Mock
     private PackageManager mMockPackageManager;
     @Mock
     private ApplicationInfo mMockApplicationInfo;
@@ -101,10 +107,13 @@
                 AppOpsManager.MODE_ERRORED);
         when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID), eq(UID)))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID_2), eq(UID)))
+                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         when(mMockContext.checkPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
                 PID, UID)).thenReturn(PackageManager.PERMISSION_DENIED);
         when(mMockDevicePolicyManager.checkDeviceIdentifierAccess(eq(PACKAGE), eq(PID),
                 eq(UID))).thenReturn(false);
+        setTelephonyMockAsService();
     }
 
     @Test
@@ -243,8 +252,8 @@
     public void testCheckReadDeviceIdentifiers_noPermissions() throws Exception {
         setupMocksForDeviceIdentifiersErrorPath();
         try {
-            TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                    SUB_ID, PID, UID, PACKAGE, MSG);
+            TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                    SUB_ID, PACKAGE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
@@ -256,8 +265,8 @@
         when(mMockContext.checkPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
                 PID, UID)).thenReturn(PackageManager.PERMISSION_GRANTED);
         assertTrue(
-                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                        SUB_ID, PID, UID, PACKAGE, MSG));
+                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
     }
 
     @Test
@@ -265,8 +274,8 @@
         when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID), eq(UID)))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(
-                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                        SUB_ID, PID, UID, PACKAGE, MSG));
+                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
     }
 
     @Test
@@ -274,8 +283,8 @@
         when(mMockAppOps.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, UID,
                 PACKAGE)).thenReturn(AppOpsManager.MODE_ALLOWED);
         assertTrue(
-                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                        SUB_ID, PID, UID, PACKAGE, MSG));
+                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
     }
 
     @Test
@@ -283,8 +292,8 @@
         when(mMockDevicePolicyManager.checkDeviceIdentifierAccess(eq(PACKAGE), eq(PID),
                 eq(UID))).thenReturn(true);
         assertTrue(
-                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                        SUB_ID, PID, UID, PACKAGE, MSG));
+                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
     }
 
     @Test
@@ -296,8 +305,8 @@
                 UID)).thenReturn(PackageManager.PERMISSION_GRANTED);
         setupMocksForDeviceIdentifiersErrorPath();
         try {
-            TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                    SUB_ID, PID, UID, PACKAGE, MSG);
+            TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                    SUB_ID, PACKAGE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
@@ -314,8 +323,8 @@
         setupMocksForDeviceIdentifiersErrorPath();
         mMockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.P;
         assertFalse(
-                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                        SUB_ID, PID, UID, PACKAGE, MSG));
+                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
     }
 
     @Test
@@ -326,8 +335,8 @@
         when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID_2), eq(UID))).thenReturn(
                 TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(
-                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                        SUB_ID, PID, UID, PACKAGE, MSG));
+                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
     }
 
     @Test
@@ -340,8 +349,8 @@
         when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID_2), eq(UID)))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(
-                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                        SUB_ID_2, PID, UID, PACKAGE, MSG));
+                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
     }
 
     @Test
@@ -354,8 +363,8 @@
         when(mMockAppOps.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, UID,
                 PACKAGE)).thenReturn(AppOpsManager.MODE_ALLOWED);
         assertTrue(
-                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                        SUB_ID, PID, UID, PACKAGE, MSG));
+                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
     }
 
     @Test
@@ -365,14 +374,79 @@
         // case.
         setupMocksForDeviceIdentifiersErrorPath();
         try {
-            TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                    SUB_ID, PID, UID, null, MSG);
+            TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                    SUB_ID, null, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
         }
     }
 
+    @Test
+    public void testCheckCallingOrSelfReadSubscriberIdentifiers_noPermissions() throws Exception {
+        setupMocksForDeviceIdentifiersErrorPath();
+        setTelephonyMockAsService();
+        when(mMockContext.checkPermission(
+                eq(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE),
+                anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
+        when(mMockAppOps.noteOpNoThrow(anyString(), anyInt(), eq(PACKAGE))).thenReturn(
+                AppOpsManager.MODE_ERRORED);
+        when(mMockDevicePolicyManager.checkDeviceIdentifierAccess(eq(PACKAGE), anyInt(),
+                anyInt())).thenReturn(false);
+        try {
+            TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mMockContext,
+                    SUB_ID, PACKAGE, MSG);
+            fail("Should have thrown SecurityException");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testCheckCallingOrSelfReadSubscriberIdentifiers_carrierPrivileges()
+            throws Exception {
+        setTelephonyMockAsService();
+        when(mMockContext.checkPermission(
+                eq(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE),
+                anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
+        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID), anyInt()))
+                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+        assertTrue(
+                TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
+    }
+
+    @Test
+    public void testCheckCallingOrSelfReadSubscriberIdentifiers_carrierPrivilegesOnOtherSub()
+            throws Exception {
+        setupMocksForDeviceIdentifiersErrorPath();
+        setTelephonyMockAsService();
+        when(mMockContext.checkPermission(
+                eq(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE),
+                anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
+        when(mMockSubscriptionManager.getActiveSubscriptionIdList(anyBoolean())).thenReturn(
+                new int[]{SUB_ID, SUB_ID_2});
+        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID_2), anyInt())).thenReturn(
+                TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+        // Carrier privilege on the other active sub shouldn't allow access to this sub.
+        try {
+            TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mMockContext,
+                    SUB_ID, PACKAGE, MSG);
+            fail("Should have thrown SecurityException");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
+    // Put mMockTelephony into service cache so that TELEPHONY_SUPPLIER will get it.
+    private void setTelephonyMockAsService() throws Exception {
+        when(mMockTelephonyBinder.queryLocalInterface(anyString())).thenReturn(mMockTelephony);
+        Field field = ServiceManager.class.getDeclaredField("sCache");
+        field.setAccessible(true);
+        ((Map<String, IBinder>) field.get(null)).put(Context.TELEPHONY_SERVICE,
+                mMockTelephonyBinder);
+    }
+
     public static class FakeSettingsConfigProvider extends FakeSettingsProvider {
         private static final String PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED =
                 DeviceConfig.NAMESPACE_PRIVACY + "/"