Enforce READ_PHONE_STATE on getCallState APIs
Enforce READ_PHONE_STATE on getCallState APIs for
apps targetting API version 31+.
Bug: 157233955
Test: atest CtsTelecomTestCases2
Change-Id: I2dc1212e4cb25f4d1f27c8c01613ebd481eebc29
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index dd2d034..c3c37b0 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -31,6 +31,7 @@
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.UiModeManager;
+import android.app.compat.CompatChanges;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -898,12 +899,46 @@
}
/**
- * @see TelecomManager#getCallState
+ * @see TelecomManager#getCallState()
+ * @deprecated this is only being kept due to an @UnsupportedAppUsage tag. Apps targeting
+ * API 31+ must use {@link #getCallStateUsingPackage(String, String)} below.
*/
+ @Deprecated
@Override
public int getCallState() {
try {
- Log.startSession("TSI.getCallState");
+ Log.startSession("TSI.getCallState(DEPRECATED)");
+ if (CompatChanges.isChangeEnabled(
+ TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION,
+ Binder.getCallingUid())) {
+ // Do not allow this API to be called on API version 31+, it should only be
+ // called on old apps using this Binder call directly.
+ throw new SecurityException("This method can only be used for applications "
+ + "targeting API version 30 or less.");
+ }
+ synchronized (mLock) {
+ return mCallsManager.getCallState();
+ }
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ /**
+ * @see TelecomManager#getCallState()
+ */
+ @Override
+ public int getCallStateUsingPackage(String callingPackage, String callingFeatureId) {
+ try {
+ Log.startSession("TSI.getCallStateUsingPackage");
+ if (CompatChanges.isChangeEnabled(
+ TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION, callingPackage,
+ Binder.getCallingUserHandle())) {
+ if (!canReadPhoneState(callingPackage, callingFeatureId, "getCallState")) {
+ throw new SecurityException("getCallState API requires READ_PHONE_STATE"
+ + " for API version 31+");
+ }
+ }
synchronized (mLock) {
return mCallsManager.getCallState();
}