Self-Managed Incoming Call Disambiguation UX.
- Handle auto-disconnect of foreground call when answering a self-managed
call.
- Enforce restriction that the PhoneAccount associated with a self-managed
CS must have a label which is the app's name.
- Ensure self-managed phone accounts can't be registered with
call provider, connection manager, or sim sub capabilities.
- Add "incoming call" UX which is shown when a new incoming call from a
self-managed CS comes in and there is an existing call for another CS.
Test: Unit, manual
Bug: 34159263
Change-Id: I371be9baa6f56c77aa83349977c0131f0e319047
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index 4fe6ed6..ea82d52 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -122,6 +122,14 @@
public void onSimCallManagerChanged(PhoneAccountRegistrar registrar) {}
}
+ /**
+ * Abstracts away dependency on the {@link PackageManager} required to fetch the label for an
+ * app.
+ */
+ public interface AppLabelProxy {
+ CharSequence getAppLabel(String packageName);
+ }
+
private static final String FILE_NAME = "phone-account-registrar-state.xml";
@VisibleForTesting
public static final int EXPECTED_STATE_VERSION = 9;
@@ -135,6 +143,7 @@
private final UserManager mUserManager;
private final SubscriptionManager mSubscriptionManager;
private final DefaultDialerCache mDefaultDialerCache;
+ private final AppLabelProxy mAppLabelProxy;
private State mState;
private UserHandle mCurrentUserHandle;
private interface PhoneAccountRegistrarWriteLock {}
@@ -142,21 +151,15 @@
new PhoneAccountRegistrarWriteLock() {};
@VisibleForTesting
- public PhoneAccountRegistrar(Context context, DefaultDialerCache defaultDialerCache) {
- this(context, FILE_NAME, defaultDialerCache);
+ public PhoneAccountRegistrar(Context context, DefaultDialerCache defaultDialerCache,
+ AppLabelProxy appLabelProxy) {
+ this(context, FILE_NAME, defaultDialerCache, appLabelProxy);
}
@VisibleForTesting
public PhoneAccountRegistrar(Context context, String fileName,
- DefaultDialerCache defaultDialerCache) {
- // TODO: This file path is subject to change -- it is storing the phone account registry
- // state file in the path /data/system/users/0/, which is likely not correct in a
- // multi-user setting.
- /** UNCOMMENT_FOR_MOVE_TO_SYSTEM_SERVICE
- String filePath = Environment.getUserSystemDirectory(UserHandle.myUserId()).
- getAbsolutePath();
- mAtomicFile = new AtomicFile(new File(filePath, fileName));
- UNCOMMENT_FOR_MOVE_TO_SYSTEM_SERVICE */
+ DefaultDialerCache defaultDialerCache, AppLabelProxy appLabelProxy) {
+
mAtomicFile = new AtomicFile(new File(context.getFilesDir(), fileName));
mState = new State();
@@ -164,6 +167,7 @@
mUserManager = UserManager.get(context);
mDefaultDialerCache = defaultDialerCache;
mSubscriptionManager = SubscriptionManager.from(mContext);
+ mAppLabelProxy = appLabelProxy;
mCurrentUserHandle = Process.myUserHandle();
read();
}
@@ -640,6 +644,27 @@
Log.i(this, "New phone account registered: " + account);
}
+ // When registering a self-managed PhoneAccount we enforce the rule that the label that the
+ // app uses is also its phone account label. Also ensure it does not attempt to declare
+ // itself as a sim acct, call manager or call provider.
+ if (account.hasCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)) {
+ // Turn off bits we don't want to be able to set (TelecomServiceImpl protects against
+ // this but we'll also prevent it from happening here, just to be safe).
+ int newCapabilities = account.getCapabilities() &
+ ~(PhoneAccount.CAPABILITY_CALL_PROVIDER |
+ PhoneAccount.CAPABILITY_CONNECTION_MANAGER |
+ PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION);
+
+ // Ensure name is correct.
+ CharSequence newLabel = mAppLabelProxy.getAppLabel(
+ account.getAccountHandle().getComponentName().getPackageName());
+
+ account = account.toBuilder()
+ .setLabel(newLabel)
+ .setCapabilities(newCapabilities)
+ .build();
+ }
+
mState.accounts.add(account);
// Set defaults and replace based on the group Id.
maybeReplaceOldAccount(account);