Enforce READ_PHONE_STATE for APIs involving call state

For API version 31+, ensure that READ_PHONE_STATE is checked on
APIs that retrieve/notify the call state of the device.

Bug: 157233955
Test: atest CtsTelecomTestCases2 CtsTelephony2TestCases
Change-Id: I9f8674a3075d3e0f75ee4f41eefce328c0fa6b91
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 1677c8c..4886789 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -25,6 +25,8 @@
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
@@ -1004,6 +1006,17 @@
             PRESENTATION_PAYPHONE})
     public @interface Presentation {}
 
+
+    /**
+     * Enable READ_PHONE_STATE protection on APIs querying and notifying call state, such as
+     * {@code TelecomManager#getCallState}, {@link TelephonyManager#getCallStateForSubscription()},
+     * and {@link android.telephony.TelephonyCallback.CallStateListener}.
+     */
+    @ChangeId
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
+    // this magic number is a bug ID
+    public static final long ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION = 157233955L;
+
     private static final String TAG = "TelecomManager";
 
 
@@ -1758,21 +1771,23 @@
      * {@link TelephonyManager#CALL_STATE_OFFHOOK}
      * {@link TelephonyManager#CALL_STATE_IDLE}
      *
-     * Note that this API does not require the
-     * {@link android.Manifest.permission#READ_PHONE_STATE} permission. This is intentional, to
-     * preserve the behavior of {@link TelephonyManager#getCallState()}, which also did not require
-     * the permission.
-     *
      * Takes into consideration both managed and self-managed calls.
+     * <p>
+     * Requires Permission:
+     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} for applications
+     * targeting API level 31+.
      *
      * @hide
      */
+    @RequiresPermission(anyOf = {READ_PRIVILEGED_PHONE_STATE,
+            android.Manifest.permission.READ_PHONE_STATE}, conditional = true)
     @SystemApi
     public @CallState int getCallState() {
         ITelecomService service = getTelecomService();
         if (service != null) {
             try {
-                return service.getCallState();
+                return service.getCallStateUsingPackage(mContext.getPackageName(),
+                        mContext.getAttributionTag());
             } catch (RemoteException e) {
                 Log.d(TAG, "RemoteException calling getCallState().", e);
             }
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 78283fa..18afde7 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -195,11 +195,18 @@
 
     /**
      * @see TelecomServiceImpl#getCallState
+     * Note: only kept around to not break app compat, however this will throw a SecurityException
+     * on API 31+.
      */
     @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     int getCallState();
 
     /**
+     * @see TelecomServiceImpl#getCallState
+     */
+    int getCallStateUsingPackage(String callingPackage, String callingFeatureId);
+
+    /**
      * @see TelecomServiceImpl#endCall
      */
     boolean endCall(String callingPackage);