Loading flags/telecom_incallservice_flags.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -6,3 +6,10 @@ flag { description: "Binds to InCallServices when call requires no call filtering on watch" bug: "282113261" } flag { name: "ecc_keyguard" namespace: "telecom" description: "Ensure that users are able to return to call from keyguard UI for ECC" bug: "306582821" } No newline at end of file src/com/android/server/telecom/InCallController.java +29 −2 Original line number Diff line number Diff line Loading @@ -22,7 +22,9 @@ import static android.os.Process.myUid; import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationManager; import android.content.AttributionSource; Loading @@ -47,7 +49,6 @@ import android.os.RemoteException; import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.permission.PermissionManager; import android.telecom.CallAudioState; import android.telecom.CallEndpoint; import android.telecom.ConnectionService; Loading @@ -66,6 +67,7 @@ import com.android.internal.telecom.IInCallService; import com.android.internal.util.ArrayUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.server.telecom.SystemStateHelper.SystemStateListener; import com.android.server.telecom.flags.FeatureFlags; import com.android.server.telecom.ui.NotificationChannelManager; import java.util.ArrayList; Loading Loading @@ -1237,11 +1239,12 @@ public class InCallController extends CallsManagerListenerBase implements private ArraySet<String> mAllCarrierPrivilegedApps = new ArraySet<>(); private ArraySet<String> mActiveCarrierPrivilegedApps = new ArraySet<>(); private FeatureFlags mFeatureFlags; public InCallController(Context context, TelecomSystem.SyncRoot lock, CallsManager callsManager, SystemStateHelper systemStateHelper, DefaultDialerCache defaultDialerCache, Timeouts.Adapter timeoutsAdapter, EmergencyCallHelper emergencyCallHelper, CarModeTracker carModeTracker, ClockProxy clockProxy) { CarModeTracker carModeTracker, ClockProxy clockProxy, FeatureFlags featureFlags) { mContext = context; mAppOpsManager = context.getSystemService(AppOpsManager.class); mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class); Loading @@ -1258,6 +1261,7 @@ public class InCallController extends CallsManagerListenerBase implements IntentFilter userAddedFilter = new IntentFilter(Intent.ACTION_USER_ADDED); userAddedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); mContext.registerReceiver(mUserAddedReceiver, userAddedFilter); mFeatureFlags = featureFlags; } private void restrictPhoneCallOps() { Loading Loading @@ -1690,6 +1694,29 @@ public class InCallController extends CallsManagerListenerBase implements @VisibleForTesting public void bringToForeground(boolean showDialpad, UserHandle callingUser) { KeyguardManager keyguardManager = mContext.getSystemService(KeyguardManager.class); boolean isLockscreenRestricted = keyguardManager != null && keyguardManager.isKeyguardLocked(); UserHandle currentUser = mCallsManager.getCurrentUserHandle(); // Handle cases when calls are placed from the keyguard UI screen, which operates under // the admin user. This needs to account for emergency calls placed from secondary/guest // users as well as the work profile. Once the screen is locked, the user should be able to // return to the call (from the keyguard UI). if (mFeatureFlags.eccKeyguard() && mCallsManager.isInEmergencyCall() && isLockscreenRestricted && !mInCallServices.containsKey(callingUser)) { // If screen is locked and the current user is the system, query calls for the work // profile user, if available. Otherwise, the user is in the secondary/guest profile, // so we can default to the system user. if (currentUser.isSystem()) { UserManager um = mContext.getSystemService(UserManager.class); UserHandle workProfileUser = findChildManagedProfileUser(currentUser, um); boolean hasWorkCalls = mCallsManager.getCalls().stream() .filter((c) -> getUserFromCall(c).equals(workProfileUser)).count() > 0; callingUser = hasWorkCalls ? workProfileUser : currentUser; } else { callingUser = currentUser; } } if (mInCallServices.containsKey(callingUser)) { for (IInCallService inCallService : mInCallServices.get(callingUser).values()) { try { Loading src/com/android/server/telecom/TelecomSystem.java +1 −1 Original line number Diff line number Diff line Loading @@ -294,7 +294,7 @@ public class TelecomSystem { EmergencyCallHelper emergencyCallHelper) { return new InCallController(context, lock, callsManager, systemStateProvider, defaultDialerCache, timeoutsAdapter, emergencyCallHelper, new CarModeTracker(), clockProxy); new CarModeTracker(), clockProxy, featureFlags); } }; Loading tests/src/com/android/server/telecom/tests/InCallControllerTests.java +1 −3 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyObject; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.matches; import static org.mockito.ArgumentMatchers.nullable; Loading @@ -36,7 +35,6 @@ import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; Loading Loading @@ -236,7 +234,7 @@ public class InCallControllerTests extends TelecomTestCase { "com.android.server.telecom.tests", null)); mInCallController = new InCallController(mMockContext, mLock, mMockCallsManager, mMockSystemStateHelper, mDefaultDialerCache, mTimeoutsAdapter, mEmergencyCallHelper, mCarModeTracker, mClockProxy); mEmergencyCallHelper, mCarModeTracker, mClockProxy, mFeatureFlags); // Capture the broadcast receiver registered. doAnswer(invocation -> { mRegisteredReceiver = invocation.getArgument(0); Loading Loading
flags/telecom_incallservice_flags.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -6,3 +6,10 @@ flag { description: "Binds to InCallServices when call requires no call filtering on watch" bug: "282113261" } flag { name: "ecc_keyguard" namespace: "telecom" description: "Ensure that users are able to return to call from keyguard UI for ECC" bug: "306582821" } No newline at end of file
src/com/android/server/telecom/InCallController.java +29 −2 Original line number Diff line number Diff line Loading @@ -22,7 +22,9 @@ import static android.os.Process.myUid; import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationManager; import android.content.AttributionSource; Loading @@ -47,7 +49,6 @@ import android.os.RemoteException; import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.permission.PermissionManager; import android.telecom.CallAudioState; import android.telecom.CallEndpoint; import android.telecom.ConnectionService; Loading @@ -66,6 +67,7 @@ import com.android.internal.telecom.IInCallService; import com.android.internal.util.ArrayUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.server.telecom.SystemStateHelper.SystemStateListener; import com.android.server.telecom.flags.FeatureFlags; import com.android.server.telecom.ui.NotificationChannelManager; import java.util.ArrayList; Loading Loading @@ -1237,11 +1239,12 @@ public class InCallController extends CallsManagerListenerBase implements private ArraySet<String> mAllCarrierPrivilegedApps = new ArraySet<>(); private ArraySet<String> mActiveCarrierPrivilegedApps = new ArraySet<>(); private FeatureFlags mFeatureFlags; public InCallController(Context context, TelecomSystem.SyncRoot lock, CallsManager callsManager, SystemStateHelper systemStateHelper, DefaultDialerCache defaultDialerCache, Timeouts.Adapter timeoutsAdapter, EmergencyCallHelper emergencyCallHelper, CarModeTracker carModeTracker, ClockProxy clockProxy) { CarModeTracker carModeTracker, ClockProxy clockProxy, FeatureFlags featureFlags) { mContext = context; mAppOpsManager = context.getSystemService(AppOpsManager.class); mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class); Loading @@ -1258,6 +1261,7 @@ public class InCallController extends CallsManagerListenerBase implements IntentFilter userAddedFilter = new IntentFilter(Intent.ACTION_USER_ADDED); userAddedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); mContext.registerReceiver(mUserAddedReceiver, userAddedFilter); mFeatureFlags = featureFlags; } private void restrictPhoneCallOps() { Loading Loading @@ -1690,6 +1694,29 @@ public class InCallController extends CallsManagerListenerBase implements @VisibleForTesting public void bringToForeground(boolean showDialpad, UserHandle callingUser) { KeyguardManager keyguardManager = mContext.getSystemService(KeyguardManager.class); boolean isLockscreenRestricted = keyguardManager != null && keyguardManager.isKeyguardLocked(); UserHandle currentUser = mCallsManager.getCurrentUserHandle(); // Handle cases when calls are placed from the keyguard UI screen, which operates under // the admin user. This needs to account for emergency calls placed from secondary/guest // users as well as the work profile. Once the screen is locked, the user should be able to // return to the call (from the keyguard UI). if (mFeatureFlags.eccKeyguard() && mCallsManager.isInEmergencyCall() && isLockscreenRestricted && !mInCallServices.containsKey(callingUser)) { // If screen is locked and the current user is the system, query calls for the work // profile user, if available. Otherwise, the user is in the secondary/guest profile, // so we can default to the system user. if (currentUser.isSystem()) { UserManager um = mContext.getSystemService(UserManager.class); UserHandle workProfileUser = findChildManagedProfileUser(currentUser, um); boolean hasWorkCalls = mCallsManager.getCalls().stream() .filter((c) -> getUserFromCall(c).equals(workProfileUser)).count() > 0; callingUser = hasWorkCalls ? workProfileUser : currentUser; } else { callingUser = currentUser; } } if (mInCallServices.containsKey(callingUser)) { for (IInCallService inCallService : mInCallServices.get(callingUser).values()) { try { Loading
src/com/android/server/telecom/TelecomSystem.java +1 −1 Original line number Diff line number Diff line Loading @@ -294,7 +294,7 @@ public class TelecomSystem { EmergencyCallHelper emergencyCallHelper) { return new InCallController(context, lock, callsManager, systemStateProvider, defaultDialerCache, timeoutsAdapter, emergencyCallHelper, new CarModeTracker(), clockProxy); new CarModeTracker(), clockProxy, featureFlags); } }; Loading
tests/src/com/android/server/telecom/tests/InCallControllerTests.java +1 −3 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyObject; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.matches; import static org.mockito.ArgumentMatchers.nullable; Loading @@ -36,7 +35,6 @@ import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; Loading Loading @@ -236,7 +234,7 @@ public class InCallControllerTests extends TelecomTestCase { "com.android.server.telecom.tests", null)); mInCallController = new InCallController(mMockContext, mLock, mMockCallsManager, mMockSystemStateHelper, mDefaultDialerCache, mTimeoutsAdapter, mEmergencyCallHelper, mCarModeTracker, mClockProxy); mEmergencyCallHelper, mCarModeTracker, mClockProxy, mFeatureFlags); // Capture the broadcast receiver registered. doAnswer(invocation -> { mRegisteredReceiver = invocation.getArgument(0); Loading