Merge "fix security exception in VoipCallMonitor" into udc-dev
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 591ce72..6e5826b 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -39,6 +39,7 @@
import android.provider.CallLog;
import android.provider.ContactsContract.Contacts;
import android.telecom.BluetoothCallQualityReport;
+import android.telecom.CallAttributes;
import android.telecom.CallAudioState;
import android.telecom.CallDiagnosticService;
import android.telecom.CallDiagnostics;
@@ -556,7 +557,25 @@
private boolean mIsSelfManaged = false;
private boolean mIsTransactionalCall = false;
- private int mOwnerPid = -1;
+ private CallingPackageIdentity mCallingPackageIdentity = new CallingPackageIdentity();
+
+ /**
+ * CallingPackageIdentity is responsible for storing properties about the calling package that
+ * initiated the call. For example, if MyVoipApp requests to add a call with Telecom, we can
+ * store their UID and PID when we are still bound to that package.
+ */
+ public static class CallingPackageIdentity {
+ public int mCallingPackageUid = -1;
+ public int mCallingPackagePid = -1;
+
+ public CallingPackageIdentity() {
+ }
+
+ CallingPackageIdentity(Bundle extras) {
+ mCallingPackageUid = extras.getInt(CallAttributes.CALLER_UID_KEY, -1);
+ mCallingPackagePid = extras.getInt(CallAttributes.CALLER_PID_KEY, -1);
+ }
+ }
/**
* Indicates whether this call is streaming.
@@ -1832,12 +1851,15 @@
setConnectionProperties(getConnectionProperties());
}
- public void setOwnerPid(int pid) {
- mOwnerPid = pid;
+ public void setCallingPackageIdentity(Bundle extras) {
+ mCallingPackageIdentity = new CallingPackageIdentity(extras);
+ // These extras should NOT be propagated to Dialer and should be removed.
+ extras.remove(CallAttributes.CALLER_PID_KEY);
+ extras.remove(CallAttributes.CALLER_UID_KEY);
}
- public int getOwnerPid() {
- return mOwnerPid;
+ public CallingPackageIdentity getCallingPackageIdentity() {
+ return mCallingPackageIdentity;
}
public void setTransactionServiceWrapper(TransactionalServiceWrapper service) {
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 0dc37fa..9503c10 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -1405,8 +1405,7 @@
// set properties for transactional call
if (extras.containsKey(TelecomManager.TRANSACTION_CALL_ID_KEY)) {
call.setIsTransactionalCall(true);
- call.setOwnerPid(extras.getInt(CallAttributes.CALLER_PID, -1));
- extras.remove(CallAttributes.CALLER_PID);
+ call.setCallingPackageIdentity(extras);
call.setConnectionCapabilities(
extras.getInt(CallAttributes.CALL_CAPABILITIES_KEY,
CallAttributes.SUPPORTS_SET_INACTIVE), true);
@@ -1717,8 +1716,7 @@
if (extras.containsKey(TelecomManager.TRANSACTION_CALL_ID_KEY)) {
call.setIsTransactionalCall(true);
- call.setOwnerPid(extras.getInt(CallAttributes.CALLER_PID, -1));
- extras.remove(CallAttributes.CALLER_PID);
+ call.setCallingPackageIdentity(extras);
call.setConnectionCapabilities(
extras.getInt(CallAttributes.CALL_CAPABILITIES_KEY,
CallAttributes.SUPPORTS_SET_INACTIVE), true);
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 47c4acf..5f1b537 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -195,14 +195,15 @@
// add extras about info used for FGS delegation
Bundle extras = new Bundle();
- extras.putInt(CallAttributes.CALLER_PID, Binder.getCallingPid());
+ extras.putInt(CallAttributes.CALLER_UID_KEY, Binder.getCallingUid());
+ extras.putInt(CallAttributes.CALLER_PID_KEY, Binder.getCallingPid());
VoipCallTransaction transaction = null;
// create transaction based on the call direction
switch (callAttributes.getDirection()) {
case DIRECTION_OUTGOING:
transaction = new OutgoingCallTransaction(callId, mContext, callAttributes,
- mCallsManager);
+ mCallsManager, extras);
break;
case DIRECTION_INCOMING:
transaction = new IncomingCallTransaction(callId, callAttributes,
diff --git a/src/com/android/server/telecom/voip/VoipCallMonitor.java b/src/com/android/server/telecom/voip/VoipCallMonitor.java
index 04af98f..67af11d 100644
--- a/src/com/android/server/telecom/voip/VoipCallMonitor.java
+++ b/src/com/android/server/telecom/voip/VoipCallMonitor.java
@@ -143,8 +143,9 @@
k -> new HashSet<>());
callList.add(call);
- mHandler.post(() -> startFGSDelegation(call.getOwnerPid(),
- phoneAccountHandle.getUserHandle().getIdentifier(), call));
+ mHandler.post(
+ () -> startFGSDelegation(call.getCallingPackageIdentity().mCallingPackagePid,
+ call.getCallingPackageIdentity().mCallingPackageUid, call));
}
}
diff --git a/tests/src/com/android/server/telecom/tests/CallTest.java b/tests/src/com/android/server/telecom/tests/CallTest.java
index 6b817d8..997e7dd 100644
--- a/tests/src/com/android/server/telecom/tests/CallTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallTest.java
@@ -26,16 +26,11 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isA;
-import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
import android.content.ComponentName;
import android.content.Intent;
@@ -43,7 +38,7 @@
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Parcel;
+import android.telecom.CallAttributes;
import android.telecom.CallerInfo;
import android.telecom.Connection;
import android.telecom.DisconnectCause;
@@ -56,12 +51,10 @@
import android.telecom.VideoProfile;
import android.telephony.CallQuality;
import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
import android.widget.Toast;
import androidx.test.ext.junit.runners.AndroidJUnit4;
-import com.android.internal.telecom.IVideoProvider;
import com.android.server.telecom.Call;
import com.android.server.telecom.CallIdMapper;
import com.android.server.telecom.CallState;
@@ -69,8 +62,6 @@
import com.android.server.telecom.CallsManager;
import com.android.server.telecom.ClockProxy;
import com.android.server.telecom.ConnectionServiceWrapper;
-import com.android.server.telecom.InCallController;
-import com.android.server.telecom.InCallController.InCallServiceInfo;
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.PhoneNumberUtilsAdapter;
import com.android.server.telecom.TelecomSystem;
@@ -640,8 +631,40 @@
verify(listener).onFailedUnknownCall(unknownCall);
}
+ /**
+ * ensure a Call object does not throw an NPE when the CallingPackageIdentity is not set and
+ * the correct values are returned when set
+ */
@Test
@SmallTest
+ public void testCallingPackageIdentity() {
+ final int packageUid = 123;
+ final int packagePid = 1;
+
+ Call call = createCall("1");
+
+ // assert default values for a Calls CallingPackageIdentity are -1 unless set via the setter
+ assertEquals(-1, call.getCallingPackageIdentity().mCallingPackageUid);
+ assertEquals(-1, call.getCallingPackageIdentity().mCallingPackagePid);
+
+ // set the Call objects CallingPackageIdentity via the setter and a bundle
+ Bundle extras = new Bundle();
+ extras.putInt(CallAttributes.CALLER_UID_KEY, packageUid);
+ extras.putInt(CallAttributes.CALLER_PID_KEY, packagePid);
+ // assert that the setter removed the extras
+ assertEquals(packageUid, extras.getInt(CallAttributes.CALLER_UID_KEY));
+ assertEquals(packagePid, extras.getInt(CallAttributes.CALLER_PID_KEY));
+ call.setCallingPackageIdentity(extras);
+ // assert that the setter removed the extras
+ assertEquals(0, extras.getInt(CallAttributes.CALLER_UID_KEY));
+ assertEquals(0, extras.getInt(CallAttributes.CALLER_PID_KEY));
+ // assert the properties are fetched correctly
+ assertEquals(packageUid, call.getCallingPackageIdentity().mCallingPackageUid);
+ assertEquals(packagePid, call.getCallingPackageIdentity().mCallingPackagePid);
+ }
+
+ @Test
+ @SmallTest
public void testOnConnectionEventNotifiesListener() {
Call.Listener listener = mock(Call.Listener.class);
Call call = createCall("1");
diff --git a/tests/src/com/android/server/telecom/tests/VoipCallMonitorTest.java b/tests/src/com/android/server/telecom/tests/VoipCallMonitorTest.java
index 7b6bd3e..346b3d8 100644
--- a/tests/src/com/android/server/telecom/tests/VoipCallMonitorTest.java
+++ b/tests/src/com/android/server/telecom/tests/VoipCallMonitorTest.java
@@ -212,6 +212,7 @@
when(call.isTransactionalCall()).thenReturn(true);
when(call.getExtras()).thenReturn(new Bundle());
when(call.getId()).thenReturn(id);
+ when(call.getCallingPackageIdentity()).thenReturn( new Call.CallingPackageIdentity() );
return call;
}
}