Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db68b354 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 12755599 from 3902f8ab to 25Q1-release

Change-Id: I1b01f0cab12a28babe6e91c4a30ab6796c09b1d6
parents 7ca36d89 3902f8ab
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -73,3 +73,12 @@ flag {
  description: "Formalizes the getLastKnownCellIdentity API that Telecom reliees on as a system api"
  bug: "327454165"
}

# OWNER=grantmenke TARGET=25Q2
flag {
  name: "allow_system_apps_resolve_voip_calls"
  is_exported: true
  namespace: "telecom"
  description: "Allow system apps such as accessibility to accept and end VOIP calls."
  bug: "353579043"
}
+69 −23
Original line number Diff line number Diff line
@@ -160,6 +160,7 @@ public class TelecomServiceImpl {
    private final FeatureFlags mFeatureFlags;
    private final com.android.internal.telephony.flags.FeatureFlags mTelephonyFeatureFlags;
    private final TelecomMetricsController mMetricsController;
    private final String mSystemUiPackageName;
    private AnomalyReporterAdapter mAnomalyReporter = new AnomalyReporterAdapterImpl();
    private final Context mContext;
    private final AppOpsManager mAppOpsManager;
@@ -1437,7 +1438,7 @@ public class TelecomServiceImpl {

                // ensure the callingPackage is not spoofed
                // skip check for privileged UIDs and throw SE if package does not match records
                if (!isPrivilegedUid(callingPackage)
                if (!isPrivilegedUid()
                        && !callingUidMatchesPackageManagerRecords(callingPackage)) {
                    EventLog.writeEvent(0x534e4554, "236813210", Binder.getCallingUid(),
                            "getCallStateUsingPackage");
@@ -1470,17 +1471,36 @@ public class TelecomServiceImpl {
            }
        }

        private boolean isPrivilegedUid(String callingPackage) {
        private boolean isPrivilegedUid() {
            int callingUid = Binder.getCallingUid();
            boolean isPrivileged = false;
            switch (callingUid) {
                case Process.ROOT_UID:
                case Process.SYSTEM_UID:
                case Process.SHELL_UID:
                    isPrivileged = true;
                    break;
            return mFeatureFlags.allowSystemAppsResolveVoipCalls()
                    ? (UserHandle.isSameApp(callingUid, Process.ROOT_UID)
                            || UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)
                            || UserHandle.isSameApp(callingUid, Process.SHELL_UID))
                    : (callingUid == Process.ROOT_UID
                            || callingUid == Process.SYSTEM_UID
                            || callingUid == Process.SHELL_UID);
        }

        private boolean isSysUiUid() {
            int callingUid = Binder.getCallingUid();
            int systemUiUid;
            if (mPackageManager != null && mSystemUiPackageName != null) {
                try {
                    systemUiUid = mPackageManager.getPackageUid(mSystemUiPackageName, 0);
                    Log.i(TAG, "isSysUiUid: callingUid = " + callingUid + "; systemUiUid = "
                            + systemUiUid);
                    return UserHandle.isSameApp(callingUid, systemUiUid);
                } catch (PackageManager.NameNotFoundException e) {
                    Log.w(TAG, "isSysUiUid: caught PackageManager NameNotFoundException = " + e);
                    return false;
                }
            } else {
                Log.w(TAG, "isSysUiUid: caught null check and returned false; "
                        + "mPackageManager = " + mPackageManager + "; mSystemUiPackageName = "
                        + mSystemUiPackageName);
            }
            return isPrivileged;
            return false;
        }

        /**
@@ -1496,11 +1516,18 @@ public class TelecomServiceImpl {
                    if (!enforceAnswerCallPermission(callingPackage, Binder.getCallingUid())) {
                        throw new SecurityException("requires ANSWER_PHONE_CALLS permission");
                    }

                    // Legacy behavior is to ignore whether the invocation is from a system app:
                    boolean isCallerPrivileged = false;
                    if (mFeatureFlags.allowSystemAppsResolveVoipCalls()) {
                        isCallerPrivileged = isPrivilegedUid() || isSysUiUid();
                        Log.i(TAG, "endCall: Binder.getCallingUid = [" +
                                Binder.getCallingUid() + "] isCallerPrivileged = " +
                                isCallerPrivileged);
                    }
                    long token = Binder.clearCallingIdentity();
                    event.setResult(ApiStats.RESULT_NORMAL);
                    try {
                        return endCallInternal(callingPackage);
                        return endCallInternal(callingPackage, isCallerPrivileged);
                    } finally {
                        Binder.restoreCallingIdentity(token);
                    }
@@ -1522,11 +1549,19 @@ public class TelecomServiceImpl {
                Log.startSession("TSI.aRC", Log.getPackageAbbreviation(packageName));
                synchronized (mLock) {
                    if (!enforceAnswerCallPermission(packageName, Binder.getCallingUid())) return;

                    // Legacy behavior is to ignore whether the invocation is from a system app:
                    boolean isCallerPrivileged = false;
                    if (mFeatureFlags.allowSystemAppsResolveVoipCalls()) {
                        isCallerPrivileged = isPrivilegedUid() || isSysUiUid();
                        Log.i(TAG, "acceptRingingCall: Binder.getCallingUid = [" +
                                Binder.getCallingUid() + "] isCallerPrivileged = " +
                                isCallerPrivileged);
                    }
                    long token = Binder.clearCallingIdentity();
                    event.setResult(ApiStats.RESULT_NORMAL);
                    try {
                        acceptRingingCallInternal(DEFAULT_VIDEO_STATE, packageName);
                        acceptRingingCallInternal(DEFAULT_VIDEO_STATE, packageName,
                                isCallerPrivileged);
                    } finally {
                        Binder.restoreCallingIdentity(token);
                    }
@@ -1549,11 +1584,18 @@ public class TelecomServiceImpl {
                Log.startSession("TSI.aRCWVS", Log.getPackageAbbreviation(packageName));
                synchronized (mLock) {
                    if (!enforceAnswerCallPermission(packageName, Binder.getCallingUid())) return;

                    // Legacy behavior is to ignore whether the invocation is from a system app:
                    boolean isCallerPrivileged = false;
                    if (mFeatureFlags.allowSystemAppsResolveVoipCalls()) {
                        isCallerPrivileged = isPrivilegedUid() || isSysUiUid();
                        Log.i(TAG, "acceptRingingCallWithVideoState: Binder.getCallingUid = "
                                + "[" + Binder.getCallingUid() + "] isCallerPrivileged = " +
                                isCallerPrivileged);
                    }
                    long token = Binder.clearCallingIdentity();
                    event.setResult(ApiStats.RESULT_NORMAL);
                    try {
                        acceptRingingCallInternal(videoState, packageName);
                        acceptRingingCallInternal(videoState, packageName, isCallerPrivileged);
                    } finally {
                        Binder.restoreCallingIdentity(token);
                    }
@@ -2918,7 +2960,8 @@ public class TelecomServiceImpl {
            SettingsSecureAdapter settingsSecureAdapter,
            FeatureFlags featureFlags,
            com.android.internal.telephony.flags.FeatureFlags telephonyFeatureFlags,
            TelecomSystem.SyncRoot lock, TelecomMetricsController metricsController) {
            TelecomSystem.SyncRoot lock, TelecomMetricsController metricsController,
            String sysUiPackageName) {
        mContext = context;
        mAppOpsManager = mContext.getSystemService(AppOpsManager.class);

@@ -2940,6 +2983,7 @@ public class TelecomServiceImpl {
        mSubscriptionManagerAdapter = subscriptionManagerAdapter;
        mSettingsSecureAdapter = settingsSecureAdapter;
        mMetricsController = metricsController;
        mSystemUiPackageName = sysUiPackageName;

        mDefaultDialerCache.observeDefaultDialerApplication(mContext.getMainExecutor(), userId -> {
            String defaultDialer = mDefaultDialerCache.getDefaultDialerApplication(userId);
@@ -3054,13 +3098,14 @@ public class TelecomServiceImpl {
        return false;
    }

    private void acceptRingingCallInternal(int videoState, String packageName) {
    private void acceptRingingCallInternal(int videoState, String packageName,
            boolean isCallerPrivileged) {
        Call call = mCallsManager.getFirstCallWithState(CallState.RINGING,
                CallState.SIMULATED_RINGING);
        if (call != null) {
            if (call.isSelfManaged()) {
            if (call.isSelfManaged() && !isCallerPrivileged) {
                Log.addEvent(call, LogUtils.Events.REQUEST_ACCEPT,
                        "self-mgd accept ignored from " + packageName);
                        "self-mgd accept ignored from non-privileged app " + packageName);
                return;
            }

@@ -3075,7 +3120,7 @@ public class TelecomServiceImpl {
    // Supporting methods for the ITelecomService interface implementation.
    //

    private boolean endCallInternal(String callingPackage) {
    private boolean endCallInternal(String callingPackage, boolean isCallerPrivileged) {
        // Always operate on the foreground call if one exists, otherwise get the first call in
        // priority order by call-state.
        Call call = mCallsManager.getForegroundCall();
@@ -3095,9 +3140,10 @@ public class TelecomServiceImpl {
                return false;
            }

            if (call.isSelfManaged()) {
            if (call.isSelfManaged() && !isCallerPrivileged) {
                Log.addEvent(call, LogUtils.Events.REQUEST_DISCONNECT,
                        "self-mgd disconnect ignored from " + callingPackage);
                        "self-mgd disconnect ignored from non-privileged app " +
                                callingPackage);
                return false;
            }

+3 −1
Original line number Diff line number Diff line
@@ -224,6 +224,7 @@ public class TelecomSystem {
            RoleManagerAdapter roleManagerAdapter,
            ContactsAsyncHelper.Factory contactsAsyncHelperFactory,
            DeviceIdleControllerAdapter deviceIdleControllerAdapter,
            String sysUiPackageName,
            Ringer.AccessibilityManagerAdapter accessibilityManagerAdapter,
            Executor asyncTaskExecutor,
            Executor asyncCallAudioTaskExecutor,
@@ -503,7 +504,8 @@ public class TelecomSystem {
                    featureFlags,
                    null,
                    mLock,
                    metricsController);
                    metricsController,
                    sysUiPackageName);
        } finally {
            Log.endSession();
        }
+5 −3
Original line number Diff line number Diff line
@@ -81,10 +81,11 @@ public class TelecomService extends Service implements TelecomSystem.Component {
        Log.d(this, "onBind");
        return new ITelecomLoader.Stub() {
            @Override
            public ITelecomService createTelecomService(IInternalServiceRetriever retriever) {
            public ITelecomService createTelecomService(IInternalServiceRetriever retriever,
                    String sysUiPackageName) {
                InternalServiceRetrieverAdapter adapter =
                        new InternalServiceRetrieverAdapter(retriever);
                initializeTelecomSystem(TelecomService.this, adapter);
                initializeTelecomSystem(TelecomService.this, adapter, sysUiPackageName);
                synchronized (getTelecomSystem().getLock()) {
                    return getTelecomSystem().getTelecomServiceImpl().getBinder();
                }
@@ -103,7 +104,7 @@ public class TelecomService extends Service implements TelecomSystem.Component {
     * @param context
     */
    static void initializeTelecomSystem(Context context,
            InternalServiceRetrieverAdapter internalServiceRetriever) {
            InternalServiceRetrieverAdapter internalServiceRetriever, String sysUiPackageName) {
        if (TelecomSystem.getInstance() == null) {
            FeatureFlags featureFlags = new FeatureFlagsImpl();
            NotificationChannelManager notificationChannelManager =
@@ -204,6 +205,7 @@ public class TelecomService extends Service implements TelecomSystem.Component {
                                    (RoleManager) context.getSystemService(Context.ROLE_SERVICE)),
                            new ContactsAsyncHelper.Factory(),
                            internalServiceRetriever.getDeviceIdleController(),
                            sysUiPackageName,
                            new Ringer.AccessibilityManagerAdapter() {
                                @Override
                                public boolean startFlashNotificationSequence(
+54 −3
Original line number Diff line number Diff line
@@ -209,6 +209,7 @@ public class TelecomServiceImplTest extends TelecomTestCase {

    private final TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() { };

    private static final String SYSTEM_UI_PACKAGE = "com.android.systemui";
    private static final String DEFAULT_DIALER_PACKAGE = "com.google.android.dialer";
    private static final UserHandle USER_HANDLE_16 = new UserHandle(16);
    private static final UserHandle USER_HANDLE_17 = new UserHandle(17);
@@ -260,7 +261,8 @@ public class TelecomServiceImplTest extends TelecomTestCase {
                mFeatureFlags,
                mTelephonyFeatureFlags,
                mLock,
                mMockTelecomMetricsController);
                mMockTelecomMetricsController,
                SYSTEM_UI_PACKAGE);
        telecomServiceImpl.setTransactionManager(mTransactionManager);
        telecomServiceImpl.setAnomalyReporterAdapter(mAnomalyReporterAdapter);
        mTSIBinder = telecomServiceImpl.getBinder();
@@ -2307,7 +2309,8 @@ public class TelecomServiceImplTest extends TelecomTestCase {
    }

    /**
     * Ensure self-managed calls cannot be ended using {@link TelecomManager#endCall()}.
     * Ensure self-managed calls cannot be ended using {@link TelecomManager#endCall()} when the
     * caller of this method is not considered privileged.
     * @throws Exception
     */
    @SmallTest
@@ -2324,7 +2327,8 @@ public class TelecomServiceImplTest extends TelecomTestCase {

    /**
     * Ensure self-managed calls cannot be answered using {@link TelecomManager#acceptRingingCall()}
     * or {@link TelecomManager#acceptRingingCall(int)}.
     * or {@link TelecomManager#acceptRingingCall(int)} when the caller of these methods is not
     * considered privileged.
     * @throws Exception
     */
    @SmallTest
@@ -2339,6 +2343,53 @@ public class TelecomServiceImplTest extends TelecomTestCase {
        verify(mFakeCallsManager, never()).answerCall(eq(call), anyInt());
    }

    /**
     * Ensure self-managed calls can be answered using {@link TelecomManager#acceptRingingCall()}
     * or {@link TelecomManager#acceptRingingCall(int)} if the caller of these methods is
     * privileged.
     * @throws Exception
     */
    @SmallTest
    @Test
    public void testCanAnswerSelfManagedCallIfPrivileged() throws Exception {
        when(mFeatureFlags.allowSystemAppsResolveVoipCalls()).thenReturn(true);
        // Configure the test so that the caller of acceptRingingCall is considered privileged:
        when(mPackageManager.getPackageUid(SYSTEM_UI_PACKAGE, 0))
                .thenReturn(Binder.getCallingUid());

        // Ensure that the call is successfully accepted:
        Call call = mock(Call.class);
        when(call.isSelfManaged()).thenReturn(true);
        when(call.getState()).thenReturn(CallState.ACTIVE);
        when(mFakeCallsManager.getFirstCallWithState(any()))
                .thenReturn(call);
        mTSIBinder.acceptRingingCall(TEST_PACKAGE);
        verify(mFakeCallsManager).answerCall(eq(call), anyInt());
    }

    /**
     * Ensure self-managed calls can be ended using {@link TelecomManager#endCall()} when the
     * caller of these methods is privileged.
     * @throws Exception
     */
    @SmallTest
    @Test
    public void testCanEndSelfManagedCallIfPrivileged() throws Exception {
        when(mFeatureFlags.allowSystemAppsResolveVoipCalls()).thenReturn(true);
        // Configure the test so that the caller of endCall is considered privileged:
        when(mPackageManager.getPackageUid(SYSTEM_UI_PACKAGE, 0))
                .thenReturn(Binder.getCallingUid());
        // Set up the call:
        Call call = mock(Call.class);
        when(call.isSelfManaged()).thenReturn(true);
        when(call.getState()).thenReturn(CallState.ACTIVE);
        when(mFakeCallsManager.getFirstCallWithState(any()))
                .thenReturn(call);
        // Ensure that the call is successfully ended:
        assertTrue(mTSIBinder.endCall(TEST_PACKAGE));
        verify(mFakeCallsManager).disconnectCall(eq(call));
    }

    @SmallTest
    @Test
    public void testGetAdnUriForPhoneAccount() throws Exception {
Loading