Loading src/com/android/server/telecom/Call.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -2651,7 +2651,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, return; return; } } mCreateConnectionProcessor = new CreateConnectionProcessor(this, mRepository, this, mCreateConnectionProcessor = new CreateConnectionProcessor(this, mRepository, this, phoneAccountRegistrar, mContext, mFlags, new Timeouts.Adapter()); phoneAccountRegistrar, mCallsManager, mContext, mFlags, new Timeouts.Adapter()); mCreateConnectionProcessor.process(); mCreateConnectionProcessor.process(); } } Loading src/com/android/server/telecom/CreateConnectionProcessor.java +57 −2 Original line number Original line Diff line number Diff line Loading @@ -37,12 +37,13 @@ import com.android.server.telecom.flags.FeatureFlags; import java.util.ArrayList; import java.util.ArrayList; import java.util.Collection; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Comparator; import java.util.HashSet; import java.util.HashSet; import java.util.Iterator; import java.util.Iterator; import java.util.List; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Collectors; /** /** Loading Loading @@ -127,6 +128,21 @@ public class CreateConnectionProcessor implements CreateConnectionResponse { } } }; }; /** * Call states which should be prioritized when sorting phone accounts. The ordering is * intentional and should NOT be modified. Other call states will not have any priority. */ private static final int[] PRIORITY_CALL_STATES = new int [] {CallState.ACTIVE, CallState.ON_HOLD, CallState.DIALING, CallState.RINGING}; private static final int DEFAULT_CALL_STATE_PRIORITY = PRIORITY_CALL_STATES.length; private static final Map<Integer, Integer> mCallStatePriorityMap = new HashMap<>(); static { for (int i = 0; i < PRIORITY_CALL_STATES.length; i++) { mCallStatePriorityMap.put(PRIORITY_CALL_STATES[i], i); } } private ITelephonyManagerAdapter mTelephonyAdapter = new ITelephonyManagerAdapterImpl(); private ITelephonyManagerAdapter mTelephonyAdapter = new ITelephonyManagerAdapterImpl(); private final Call mCall; private final Call mCall; Loading @@ -136,6 +152,7 @@ public class CreateConnectionProcessor implements CreateConnectionResponse { private CreateConnectionResponse mCallResponse; private CreateConnectionResponse mCallResponse; private DisconnectCause mLastErrorDisconnectCause; private DisconnectCause mLastErrorDisconnectCause; private final PhoneAccountRegistrar mPhoneAccountRegistrar; private final PhoneAccountRegistrar mPhoneAccountRegistrar; private final CallsManager mCallsManager; private final Context mContext; private final Context mContext; private final FeatureFlags mFlags; private final FeatureFlags mFlags; private final Timeouts.Adapter mTimeoutsAdapter; private final Timeouts.Adapter mTimeoutsAdapter; Loading @@ -148,6 +165,7 @@ public class CreateConnectionProcessor implements CreateConnectionResponse { ConnectionServiceRepository repository, ConnectionServiceRepository repository, CreateConnectionResponse response, CreateConnectionResponse response, PhoneAccountRegistrar phoneAccountRegistrar, PhoneAccountRegistrar phoneAccountRegistrar, CallsManager callsManager, Context context, Context context, FeatureFlags featureFlags, FeatureFlags featureFlags, Timeouts.Adapter timeoutsAdapter) { Timeouts.Adapter timeoutsAdapter) { Loading @@ -156,6 +174,7 @@ public class CreateConnectionProcessor implements CreateConnectionResponse { mRepository = repository; mRepository = repository; mCallResponse = response; mCallResponse = response; mPhoneAccountRegistrar = phoneAccountRegistrar; mPhoneAccountRegistrar = phoneAccountRegistrar; mCallsManager = callsManager; mContext = context; mContext = context; mConnectionAttempt = 0; mConnectionAttempt = 0; mFlags = featureFlags; mFlags = featureFlags; Loading Loading @@ -693,6 +712,23 @@ public class CreateConnectionProcessor implements CreateConnectionResponse { return retval; return retval; } } // Sort accounts by ongoing call states Set<Integer> callStatesAccount1 = mCallsManager.getCalls().stream() .filter(c -> Objects.equals(account1.getAccountHandle(), c.getTargetPhoneAccount())) .map(Call::getState).collect(Collectors.toSet()); Set<Integer> callStatesAccount2 = mCallsManager.getCalls().stream() .filter(c -> Objects.equals(account2.getAccountHandle(), c.getTargetPhoneAccount())) .map(Call::getState).collect(Collectors.toSet()); int account1Priority = computeCallStatePriority(callStatesAccount1); int account2Priority = computeCallStatePriority(callStatesAccount2); Log.d(this, "account1: %s, call state priority: %s", account1, account1Priority); Log.d(this, "account2: %s, call state priority: %s", account2, account2Priority); if (account1Priority != account2Priority) { return account1Priority < account2Priority ? -1 : 1; } // Prefer the user's choice if all PhoneAccounts are associated with valid logical // Prefer the user's choice if all PhoneAccounts are associated with valid logical // slots. // slots. if (userPreferredAccount != null) { if (userPreferredAccount != null) { Loading Loading @@ -731,6 +767,25 @@ public class CreateConnectionProcessor implements CreateConnectionResponse { }); }); } } /** * Computes the call state priority based on the passed in call states associated with the * calls present on the phone account. The lower the value, the higher the priority (i.e. * ACTIVE (0) < HOLDING (1) < DIALING (2) < RINGING (3) equates to ACTIVE holding the highest * priority). */ private int computeCallStatePriority(Set<Integer> callStates) { int priority = DEFAULT_CALL_STATE_PRIORITY; for (int state: callStates) { if (priority == mCallStatePriorityMap.get(CallState.ACTIVE)) { return priority; } else if (mCallStatePriorityMap.containsKey(state) && priority > mCallStatePriorityMap.get(state)) { priority = mCallStatePriorityMap.get(state); } } return priority; } private static String nullToEmpty(String str) { private static String nullToEmpty(String str) { return str == null ? "" : str; return str == null ? "" : str; } } Loading src/com/android/server/telecom/PhoneAccountRegistrar.java +20 −9 Original line number Original line Diff line number Diff line Loading @@ -181,7 +181,7 @@ public class PhoneAccountRegistrar { private final TelecomSystem.SyncRoot mLock; private final TelecomSystem.SyncRoot mLock; private State mState; private State mState; private UserHandle mCurrentUserHandle; private UserHandle mCurrentUserHandle; private String mTestPhoneAccountPackageNameFilter; private final Set<String> mTestPhoneAccountPackageNameFilters; private interface PhoneAccountRegistrarWriteLock {} private interface PhoneAccountRegistrarWriteLock {} private final PhoneAccountRegistrarWriteLock mWriteLock = private final PhoneAccountRegistrarWriteLock mWriteLock = new PhoneAccountRegistrarWriteLock() {}; new PhoneAccountRegistrarWriteLock() {}; Loading Loading @@ -215,6 +215,7 @@ public class PhoneAccountRegistrar { mAppLabelProxy = appLabelProxy; mAppLabelProxy = appLabelProxy; mCurrentUserHandle = Process.myUserHandle(); mCurrentUserHandle = Process.myUserHandle(); mTelecomFeatureFlags = telecomFeatureFlags; mTelecomFeatureFlags = telecomFeatureFlags; mTestPhoneAccountPackageNameFilters = new HashSet<>(); if (telephonyFeatureFlags != null) { if (telephonyFeatureFlags != null) { mTelephonyFeatureFlags = telephonyFeatureFlags; mTelephonyFeatureFlags = telephonyFeatureFlags; Loading Loading @@ -607,23 +608,33 @@ public class PhoneAccountRegistrar { * {@link PhoneAccount}s with the same package name. * {@link PhoneAccount}s with the same package name. */ */ public void setTestPhoneAccountPackageNameFilter(String packageNameFilter) { public void setTestPhoneAccountPackageNameFilter(String packageNameFilter) { mTestPhoneAccountPackageNameFilter = packageNameFilter; mTestPhoneAccountPackageNameFilters.clear(); Log.i(this, "filter set for PhoneAccounts, packageName=" + packageNameFilter); if (packageNameFilter == null) { return; } String [] pkgNamesFilter = packageNameFilter.split(","); mTestPhoneAccountPackageNameFilters.addAll(Arrays.asList(pkgNamesFilter)); StringBuilder pkgNames = new StringBuilder(); for (int i = 0; i < pkgNamesFilter.length; i++) { pkgNames.append(pkgNamesFilter[i]) .append(i != pkgNamesFilter.length - 1 ? ", " : "."); } Log.i(this, "filter set for PhoneAccounts, packageNames: %s", pkgNames.toString()); } } /** /** * Filter the given {@link List<PhoneAccount>} and keep only {@link PhoneAccount}s that have the * Filter the given {@link List<PhoneAccount>} and keep only {@link PhoneAccount}s that have the * #mTestPhoneAccountPackageNameFilter. * #mTestPhoneAccountPackageNameFilters. * @param accounts List of {@link PhoneAccount}s to filter. * @param accounts List of {@link PhoneAccount}s to filter. * @return new list of filtered {@link PhoneAccount}s. * @return new list of filtered {@link PhoneAccount}s. */ */ public List<PhoneAccount> filterRestrictedPhoneAccounts(List<PhoneAccount> accounts) { public List<PhoneAccount> filterRestrictedPhoneAccounts(List<PhoneAccount> accounts) { if (TextUtils.isEmpty(mTestPhoneAccountPackageNameFilter)) { if (mTestPhoneAccountPackageNameFilters.isEmpty()) { return new ArrayList<>(accounts); return new ArrayList<>(accounts); } } // Remove all PhoneAccounts that do not have the same package name as the filter. // Remove all PhoneAccounts that do not have the same package name (prefix) as the filter. return accounts.stream().filter(account -> mTestPhoneAccountPackageNameFilter.equals( return accounts.stream().filter(account -> mTestPhoneAccountPackageNameFilters account.getAccountHandle().getComponentName().getPackageName())) .contains(account.getAccountHandle().getComponentName().getPackageName())) .collect(Collectors.toList()); .collect(Collectors.toList()); } } Loading Loading @@ -1977,7 +1988,7 @@ public class PhoneAccountRegistrar { } } pw.decreaseIndent(); pw.decreaseIndent(); pw.increaseIndent(); pw.increaseIndent(); pw.println("test emergency PhoneAccount filter: " + mTestPhoneAccountPackageNameFilter); pw.println("test emergency PhoneAccount filter: " + mTestPhoneAccountPackageNameFilters); pw.decreaseIndent(); pw.decreaseIndent(); } } } } Loading Loading
src/com/android/server/telecom/Call.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -2651,7 +2651,7 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, return; return; } } mCreateConnectionProcessor = new CreateConnectionProcessor(this, mRepository, this, mCreateConnectionProcessor = new CreateConnectionProcessor(this, mRepository, this, phoneAccountRegistrar, mContext, mFlags, new Timeouts.Adapter()); phoneAccountRegistrar, mCallsManager, mContext, mFlags, new Timeouts.Adapter()); mCreateConnectionProcessor.process(); mCreateConnectionProcessor.process(); } } Loading
src/com/android/server/telecom/CreateConnectionProcessor.java +57 −2 Original line number Original line Diff line number Diff line Loading @@ -37,12 +37,13 @@ import com.android.server.telecom.flags.FeatureFlags; import java.util.ArrayList; import java.util.ArrayList; import java.util.Collection; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Comparator; import java.util.HashSet; import java.util.HashSet; import java.util.Iterator; import java.util.Iterator; import java.util.List; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Collectors; /** /** Loading Loading @@ -127,6 +128,21 @@ public class CreateConnectionProcessor implements CreateConnectionResponse { } } }; }; /** * Call states which should be prioritized when sorting phone accounts. The ordering is * intentional and should NOT be modified. Other call states will not have any priority. */ private static final int[] PRIORITY_CALL_STATES = new int [] {CallState.ACTIVE, CallState.ON_HOLD, CallState.DIALING, CallState.RINGING}; private static final int DEFAULT_CALL_STATE_PRIORITY = PRIORITY_CALL_STATES.length; private static final Map<Integer, Integer> mCallStatePriorityMap = new HashMap<>(); static { for (int i = 0; i < PRIORITY_CALL_STATES.length; i++) { mCallStatePriorityMap.put(PRIORITY_CALL_STATES[i], i); } } private ITelephonyManagerAdapter mTelephonyAdapter = new ITelephonyManagerAdapterImpl(); private ITelephonyManagerAdapter mTelephonyAdapter = new ITelephonyManagerAdapterImpl(); private final Call mCall; private final Call mCall; Loading @@ -136,6 +152,7 @@ public class CreateConnectionProcessor implements CreateConnectionResponse { private CreateConnectionResponse mCallResponse; private CreateConnectionResponse mCallResponse; private DisconnectCause mLastErrorDisconnectCause; private DisconnectCause mLastErrorDisconnectCause; private final PhoneAccountRegistrar mPhoneAccountRegistrar; private final PhoneAccountRegistrar mPhoneAccountRegistrar; private final CallsManager mCallsManager; private final Context mContext; private final Context mContext; private final FeatureFlags mFlags; private final FeatureFlags mFlags; private final Timeouts.Adapter mTimeoutsAdapter; private final Timeouts.Adapter mTimeoutsAdapter; Loading @@ -148,6 +165,7 @@ public class CreateConnectionProcessor implements CreateConnectionResponse { ConnectionServiceRepository repository, ConnectionServiceRepository repository, CreateConnectionResponse response, CreateConnectionResponse response, PhoneAccountRegistrar phoneAccountRegistrar, PhoneAccountRegistrar phoneAccountRegistrar, CallsManager callsManager, Context context, Context context, FeatureFlags featureFlags, FeatureFlags featureFlags, Timeouts.Adapter timeoutsAdapter) { Timeouts.Adapter timeoutsAdapter) { Loading @@ -156,6 +174,7 @@ public class CreateConnectionProcessor implements CreateConnectionResponse { mRepository = repository; mRepository = repository; mCallResponse = response; mCallResponse = response; mPhoneAccountRegistrar = phoneAccountRegistrar; mPhoneAccountRegistrar = phoneAccountRegistrar; mCallsManager = callsManager; mContext = context; mContext = context; mConnectionAttempt = 0; mConnectionAttempt = 0; mFlags = featureFlags; mFlags = featureFlags; Loading Loading @@ -693,6 +712,23 @@ public class CreateConnectionProcessor implements CreateConnectionResponse { return retval; return retval; } } // Sort accounts by ongoing call states Set<Integer> callStatesAccount1 = mCallsManager.getCalls().stream() .filter(c -> Objects.equals(account1.getAccountHandle(), c.getTargetPhoneAccount())) .map(Call::getState).collect(Collectors.toSet()); Set<Integer> callStatesAccount2 = mCallsManager.getCalls().stream() .filter(c -> Objects.equals(account2.getAccountHandle(), c.getTargetPhoneAccount())) .map(Call::getState).collect(Collectors.toSet()); int account1Priority = computeCallStatePriority(callStatesAccount1); int account2Priority = computeCallStatePriority(callStatesAccount2); Log.d(this, "account1: %s, call state priority: %s", account1, account1Priority); Log.d(this, "account2: %s, call state priority: %s", account2, account2Priority); if (account1Priority != account2Priority) { return account1Priority < account2Priority ? -1 : 1; } // Prefer the user's choice if all PhoneAccounts are associated with valid logical // Prefer the user's choice if all PhoneAccounts are associated with valid logical // slots. // slots. if (userPreferredAccount != null) { if (userPreferredAccount != null) { Loading Loading @@ -731,6 +767,25 @@ public class CreateConnectionProcessor implements CreateConnectionResponse { }); }); } } /** * Computes the call state priority based on the passed in call states associated with the * calls present on the phone account. The lower the value, the higher the priority (i.e. * ACTIVE (0) < HOLDING (1) < DIALING (2) < RINGING (3) equates to ACTIVE holding the highest * priority). */ private int computeCallStatePriority(Set<Integer> callStates) { int priority = DEFAULT_CALL_STATE_PRIORITY; for (int state: callStates) { if (priority == mCallStatePriorityMap.get(CallState.ACTIVE)) { return priority; } else if (mCallStatePriorityMap.containsKey(state) && priority > mCallStatePriorityMap.get(state)) { priority = mCallStatePriorityMap.get(state); } } return priority; } private static String nullToEmpty(String str) { private static String nullToEmpty(String str) { return str == null ? "" : str; return str == null ? "" : str; } } Loading
src/com/android/server/telecom/PhoneAccountRegistrar.java +20 −9 Original line number Original line Diff line number Diff line Loading @@ -181,7 +181,7 @@ public class PhoneAccountRegistrar { private final TelecomSystem.SyncRoot mLock; private final TelecomSystem.SyncRoot mLock; private State mState; private State mState; private UserHandle mCurrentUserHandle; private UserHandle mCurrentUserHandle; private String mTestPhoneAccountPackageNameFilter; private final Set<String> mTestPhoneAccountPackageNameFilters; private interface PhoneAccountRegistrarWriteLock {} private interface PhoneAccountRegistrarWriteLock {} private final PhoneAccountRegistrarWriteLock mWriteLock = private final PhoneAccountRegistrarWriteLock mWriteLock = new PhoneAccountRegistrarWriteLock() {}; new PhoneAccountRegistrarWriteLock() {}; Loading Loading @@ -215,6 +215,7 @@ public class PhoneAccountRegistrar { mAppLabelProxy = appLabelProxy; mAppLabelProxy = appLabelProxy; mCurrentUserHandle = Process.myUserHandle(); mCurrentUserHandle = Process.myUserHandle(); mTelecomFeatureFlags = telecomFeatureFlags; mTelecomFeatureFlags = telecomFeatureFlags; mTestPhoneAccountPackageNameFilters = new HashSet<>(); if (telephonyFeatureFlags != null) { if (telephonyFeatureFlags != null) { mTelephonyFeatureFlags = telephonyFeatureFlags; mTelephonyFeatureFlags = telephonyFeatureFlags; Loading Loading @@ -607,23 +608,33 @@ public class PhoneAccountRegistrar { * {@link PhoneAccount}s with the same package name. * {@link PhoneAccount}s with the same package name. */ */ public void setTestPhoneAccountPackageNameFilter(String packageNameFilter) { public void setTestPhoneAccountPackageNameFilter(String packageNameFilter) { mTestPhoneAccountPackageNameFilter = packageNameFilter; mTestPhoneAccountPackageNameFilters.clear(); Log.i(this, "filter set for PhoneAccounts, packageName=" + packageNameFilter); if (packageNameFilter == null) { return; } String [] pkgNamesFilter = packageNameFilter.split(","); mTestPhoneAccountPackageNameFilters.addAll(Arrays.asList(pkgNamesFilter)); StringBuilder pkgNames = new StringBuilder(); for (int i = 0; i < pkgNamesFilter.length; i++) { pkgNames.append(pkgNamesFilter[i]) .append(i != pkgNamesFilter.length - 1 ? ", " : "."); } Log.i(this, "filter set for PhoneAccounts, packageNames: %s", pkgNames.toString()); } } /** /** * Filter the given {@link List<PhoneAccount>} and keep only {@link PhoneAccount}s that have the * Filter the given {@link List<PhoneAccount>} and keep only {@link PhoneAccount}s that have the * #mTestPhoneAccountPackageNameFilter. * #mTestPhoneAccountPackageNameFilters. * @param accounts List of {@link PhoneAccount}s to filter. * @param accounts List of {@link PhoneAccount}s to filter. * @return new list of filtered {@link PhoneAccount}s. * @return new list of filtered {@link PhoneAccount}s. */ */ public List<PhoneAccount> filterRestrictedPhoneAccounts(List<PhoneAccount> accounts) { public List<PhoneAccount> filterRestrictedPhoneAccounts(List<PhoneAccount> accounts) { if (TextUtils.isEmpty(mTestPhoneAccountPackageNameFilter)) { if (mTestPhoneAccountPackageNameFilters.isEmpty()) { return new ArrayList<>(accounts); return new ArrayList<>(accounts); } } // Remove all PhoneAccounts that do not have the same package name as the filter. // Remove all PhoneAccounts that do not have the same package name (prefix) as the filter. return accounts.stream().filter(account -> mTestPhoneAccountPackageNameFilter.equals( return accounts.stream().filter(account -> mTestPhoneAccountPackageNameFilters account.getAccountHandle().getComponentName().getPackageName())) .contains(account.getAccountHandle().getComponentName().getPackageName())) .collect(Collectors.toList()); .collect(Collectors.toList()); } } Loading Loading @@ -1977,7 +1988,7 @@ public class PhoneAccountRegistrar { } } pw.decreaseIndent(); pw.decreaseIndent(); pw.increaseIndent(); pw.increaseIndent(); pw.println("test emergency PhoneAccount filter: " + mTestPhoneAccountPackageNameFilter); pw.println("test emergency PhoneAccount filter: " + mTestPhoneAccountPackageNameFilters); pw.decreaseIndent(); pw.decreaseIndent(); } } } } Loading