Provide enable property on phone accounts.
Bug: 20303449
Change-Id: I4b9cb0e29377233ed4fc01757570351ee6e5856e
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 34647a2..92b1600 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -23,22 +23,22 @@
<!-- Prevents the activity manager from delaying any activity-start
requests by this package, including requests immediately after
the user presses "home". -->
+ <uses-permission android:name="android.permission.BIND_CONNECTION_SERVICE" />
+ <uses-permission android:name="android.permission.BIND_INCALL_SERVICE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ <uses-permission android:name="android.permission.BROADCAST_CALLLOG_INFO" />
+ <uses-permission android:name="android.permission.BROADCAST_PHONE_ACCOUNT_REGISTRATION" />
<uses-permission android:name="android.permission.CALL_PRIVILEGED" />
- <uses-permission android:name="android.permission.MANAGE_USERS" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+ <uses-permission android:name="android.permission.MANAGE_USERS" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+ <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.STOP_APP_SWITCHES" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
- <uses-permission android:name="android.permission.BIND_CONNECTION_SERVICE" />
- <uses-permission android:name="android.permission.BIND_INCALL_SERVICE" />
- <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
- <uses-permission android:name="android.permission.BROADCAST_CALLLOG_INFO" />
- <uses-permission android:name="android.permission.BROADCAST_PHONE_ACCOUNT_REGISTRATION" />
<permission
android:name="android.permission.BROADCAST_CALLLOG_INFO"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 181a7f7..8d2cae1 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -18,7 +18,7 @@
<!-- Official label of the Telecomm/Phone app, as seen in "Manage Applications"
and other settings UIs. This is the "app name" used in notification, recents,
and app info screens. -->
- <string name="telecommAppLabel" product="default">Phone</string>
+ <string name="telecommAppLabel" product="default">Phone - Call Management</string>
<!-- Name for an "unknown" caller. -->
<string name="unknown">Unknown</string>
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 845fe7f..0946892 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -527,7 +527,7 @@
Call call = getNewOutgoingCall(handle);
List<PhoneAccountHandle> accounts =
- mPhoneAccountRegistrar.getCallCapablePhoneAccounts(handle.getScheme());
+ mPhoneAccountRegistrar.getCallCapablePhoneAccounts(handle.getScheme(), false);
Log.v(this, "startOutgoingCall found accounts = " + accounts);
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index c908b92..3531df6 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -194,7 +194,7 @@
}
}
- List<PhoneAccountHandle> outgoing = getCallCapablePhoneAccounts(uriScheme);
+ List<PhoneAccountHandle> outgoing = getCallCapablePhoneAccounts(uriScheme, false);
switch (outgoing.size()) {
case 0:
// There are no accounts, so there can be no default
@@ -348,6 +348,20 @@
mCurrentUserHandle = userHandle;
}
+ public void enablePhoneAccount(PhoneAccountHandle accountHandle, boolean isEnabled) {
+ PhoneAccount account = getPhoneAccount(accountHandle);
+ if (account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
+ // We never change the enabled state of SIM-based accounts.
+ return;
+ }
+
+ if (account != null && account.isEnabled() != isEnabled) {
+ account.setIsEnabled(isEnabled);
+ write();
+ fireAccountsChanged();
+ }
+ }
+
private boolean isVisibleForUser(PhoneAccount account) {
if (account == null) {
return false;
@@ -414,15 +428,16 @@
/**
* Retrieves a list of all {@link PhoneAccountHandle}s registered.
+ * Only returns accounts which are enabled.
*
* @return The list of {@link PhoneAccountHandle}s.
*/
public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
- return getPhoneAccountHandles(0, null, null);
+ return getPhoneAccountHandles(0, null, null, false);
}
public List<PhoneAccount> getAllPhoneAccounts() {
- return getPhoneAccounts(0, null, null);
+ return getPhoneAccounts(0, null, null, false);
}
/**
@@ -432,8 +447,10 @@
* @param uriScheme The URI scheme.
* @return The phone account handles.
*/
- public List<PhoneAccountHandle> getCallCapablePhoneAccounts(String uriScheme) {
- return getPhoneAccountHandles(PhoneAccount.CAPABILITY_CALL_PROVIDER, uriScheme, null);
+ public List<PhoneAccountHandle> getCallCapablePhoneAccounts(
+ String uriScheme, boolean includeDisabledAccounts) {
+ return getPhoneAccountHandles(
+ PhoneAccount.CAPABILITY_CALL_PROVIDER, uriScheme, null, includeDisabledAccounts);
}
/**
@@ -442,7 +459,7 @@
public List<PhoneAccountHandle> getSimPhoneAccounts() {
return getPhoneAccountHandles(
PhoneAccount.CAPABILITY_CALL_PROVIDER | PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION,
- null, null);
+ null, null, false);
}
/**
@@ -452,7 +469,7 @@
* @return The phone account handles.
*/
public List<PhoneAccountHandle> getPhoneAccountsForPackage(String packageName) {
- return getPhoneAccountHandles(0, null, packageName);
+ return getPhoneAccountHandles(0, null, packageName, false);
}
/**
@@ -461,7 +478,7 @@
* @return The phone account handles.
*/
public List<PhoneAccountHandle> getConnectionManagerPhoneAccounts() {
- return getPhoneAccountHandles(PhoneAccount.CAPABILITY_CONNECTION_MANAGER, null, null);
+ return getPhoneAccountHandles(PhoneAccount.CAPABILITY_CONNECTION_MANAGER, null, null, true);
}
// TODO: Should we implement an artificial limit for # of accounts associated with a single
@@ -489,11 +506,22 @@
Log.d(this, "addOrReplacePhoneAccount(%s -> %s)",
account.getAccountHandle(), account);
+ // Start _enabled_ property as false.
+ // !!! IMPORTANT !!! It is important that we do not read the enabled state that the
+ // source app provides or else an third party app could enable itself.
+ boolean isEnabled = false;
+
PhoneAccount oldAccount = getPhoneAccount(account.getAccountHandle());
if (oldAccount != null) {
mState.accounts.remove(oldAccount);
+ isEnabled = oldAccount.isEnabled();
}
+
mState.accounts.add(account);
+ // Reset enabled state to whatever the value was if the account was already registered,
+ // or _true_ if this is a SIM-based account. All SIM-based accounts are always enabled.
+ account.setIsEnabled(
+ isEnabled || account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION));
write();
fireAccountsChanged();
@@ -636,9 +664,14 @@
* and package name.
*/
private List<PhoneAccountHandle> getPhoneAccountHandles(
- int capabilities, String uriScheme, String packageName) {
+ int capabilities,
+ String uriScheme,
+ String packageName,
+ boolean includeDisabledAccounts) {
List<PhoneAccountHandle> handles = new ArrayList<>();
- for (PhoneAccount account : getPhoneAccounts(capabilities, uriScheme, packageName)) {
+
+ for (PhoneAccount account : getPhoneAccounts(
+ capabilities, uriScheme, packageName, includeDisabledAccounts)) {
handles.add(account.getAccountHandle());
}
return handles;
@@ -654,9 +687,17 @@
* @param packageName Package name of the PhoneAccount. {@code null} bypasses packageName check.
*/
private List<PhoneAccount> getPhoneAccounts(
- int capabilities, String uriScheme, String packageName) {
+ int capabilities,
+ String uriScheme,
+ String packageName,
+ boolean includeDisabledAccounts) {
List<PhoneAccount> accounts = new ArrayList<>(mState.accounts.size());
for (PhoneAccount m : mState.accounts) {
+ if (!(m.isEnabled() || includeDisabledAccounts)) {
+ // Do not include disabled accounts.
+ continue;
+ }
+
if (capabilities != 0 && !m.hasCapabilities(capabilities)) {
// Account doesn't have the right capabilities; skip this one.
continue;
@@ -1053,6 +1094,7 @@
private static final String SHORT_DESCRIPTION = "short_description";
private static final String SUPPORTED_URI_SCHEMES = "supported_uri_schemes";
private static final String ICON = "icon";
+ private static final String ENABLED = "enabled";
@Override
public void writeToXml(PhoneAccount o, XmlSerializer serializer, Context context)
@@ -1075,6 +1117,7 @@
writeTextIfNonNull(LABEL, o.getLabel(), serializer);
writeTextIfNonNull(SHORT_DESCRIPTION, o.getShortDescription(), serializer);
writeStringList(SUPPORTED_URI_SCHEMES, o.getSupportedUriSchemes(), serializer);
+ writeTextIfNonNull(ENABLED, o.isEnabled() ? "true" : "false" , serializer);
serializer.endTag(null, CLASS_PHONE_ACCOUNT);
}
@@ -1097,6 +1140,7 @@
String shortDescription = null;
List<String> supportedUriSchemes = null;
Icon icon = null;
+ boolean enabled = false;
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
if (parser.getName().equals(ACCOUNT_HANDLE)) {
@@ -1139,6 +1183,9 @@
} else if (parser.getName().equals(ICON)) {
parser.next();
icon = readIcon(parser);
+ } else if (parser.getName().equals(ENABLED)) {
+ parser.next();
+ enabled = "true".equalsIgnoreCase(parser.getText());
}
}
@@ -1176,7 +1223,8 @@
.setCapabilities(capabilities)
.setShortDescription(shortDescription)
.setSupportedUriSchemes(supportedUriSchemes)
- .setHighlightColor(highlightColor);
+ .setHighlightColor(highlightColor)
+ .setIsEnabled(enabled);
if (icon != null) {
builder.setIcon(icon);
@@ -1187,7 +1235,7 @@
// TODO: Need to set tint.
}
- return builder.build();
+ builder.build();
}
return null;
}
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index b219358..bed6c6c 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -124,7 +124,8 @@
}
@Override
- public List<PhoneAccountHandle> getCallCapablePhoneAccounts(String callingPackage) {
+ public List<PhoneAccountHandle> getCallCapablePhoneAccounts(
+ boolean includeDisabledAccounts, String callingPackage) {
if (!canReadPhoneState(callingPackage, "getDefaultOutgoingPhoneAccount")) {
return Collections.emptyList();
}
@@ -135,7 +136,8 @@
// TODO: Does this isVisible check actually work considering we are clearing
// the calling identity?
return filterForAccountsVisibleToCaller(
- mPhoneAccountRegistrar.getCallCapablePhoneAccounts(null));
+ mPhoneAccountRegistrar.getCallCapablePhoneAccounts(
+ null, includeDisabledAccounts));
} catch (Exception e) {
Log.e(this, e, "getCallCapablePhoneAccounts");
throw e;
@@ -158,7 +160,7 @@
// TODO: Does this isVisible check actually work considering we are clearing
// the calling identity?
return filterForAccountsVisibleToCaller(
- mPhoneAccountRegistrar.getCallCapablePhoneAccounts(uriScheme));
+ mPhoneAccountRegistrar.getCallCapablePhoneAccounts(uriScheme, false));
} catch (Exception e) {
Log.e(this, e, "getPhoneAccountsSupportingScheme %s", uriScheme);
throw e;
@@ -825,6 +827,23 @@
}
/**
+ * @see android.telecom.TelecomManager#enablePhoneAccount
+ */
+ @Override
+ public void enablePhoneAccount(PhoneAccountHandle accountHandle, boolean isEnabled) {
+ enforceModifyPermission();
+ synchronized (mLock) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ // enable/disable phone account
+ mPhoneAccountRegistrar.enablePhoneAccount(accountHandle, isEnabled);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ }
+
+ /**
* Dumps the current state of the TelecomService. Used when generating problem reports.
*
* @param fd The file descriptor.
diff --git a/src/com/android/server/telecom/TelephonyUtil.java b/src/com/android/server/telecom/TelephonyUtil.java
index 04f08f9..5827e73 100644
--- a/src/com/android/server/telecom/TelephonyUtil.java
+++ b/src/com/android/server/telecom/TelephonyUtil.java
@@ -51,7 +51,9 @@
return PhoneAccount.builder(DEFAULT_EMERGENCY_PHONE_ACCOUNT_HANDLE, "E")
.setCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
PhoneAccount.CAPABILITY_CALL_PROVIDER |
- PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS).build();
+ PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS)
+ .setIsEnabled(true)
+ .build();
}
static boolean isPstnComponentName(ComponentName componentName) {
diff --git a/src/com/android/server/telecom/settings/EnableAccountPreferenceActivity.java b/src/com/android/server/telecom/settings/EnableAccountPreferenceActivity.java
index b68c8ff..383b416 100644
--- a/src/com/android/server/telecom/settings/EnableAccountPreferenceActivity.java
+++ b/src/com/android/server/telecom/settings/EnableAccountPreferenceActivity.java
@@ -16,8 +16,10 @@
package com.android.server.telecom.settings;
+import android.app.ActionBar;
import android.app.Activity;
import android.os.Bundle;
+import android.view.MenuItem;
public class EnableAccountPreferenceActivity extends Activity {
@Override
@@ -27,5 +29,22 @@
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new EnableAccountPreferenceFragment())
.commit();
+
+ ActionBar actionBar = getActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ }
}
+
+ /** ${inheritDoc} */
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
}
diff --git a/src/com/android/server/telecom/settings/EnableAccountPreferenceFragment.java b/src/com/android/server/telecom/settings/EnableAccountPreferenceFragment.java
index 48e22b6f..83eb113 100644
--- a/src/com/android/server/telecom/settings/EnableAccountPreferenceFragment.java
+++ b/src/com/android/server/telecom/settings/EnableAccountPreferenceFragment.java
@@ -38,7 +38,7 @@
*/
public class EnableAccountPreferenceFragment extends PreferenceFragment {
- private static final class AccountSwitchPreference extends SwitchPreference {
+ private final class AccountSwitchPreference extends SwitchPreference {
private final PhoneAccount mAccount;
public AccountSwitchPreference(Context context, PhoneAccount account) {
@@ -51,6 +51,7 @@
if (icon != null) {
setIcon(icon.loadDrawable(context));
}
+ setChecked(account.isEnabled());
}
/** ${inheritDoc} */
@@ -58,7 +59,7 @@
protected void onClick() {
super.onClick();
- // TODO: Handle enabling/disabling phone accounts
+ mTelecomManager.enablePhoneAccount(mAccount.getAccountHandle(), isChecked());
}
}
@@ -75,11 +76,17 @@
public void onResume() {
super.onResume();
- addPreferencesFromResource(R.xml.enable_account_preference);
-
- List<PhoneAccountHandle> accountHandles = mTelecomManager.getCallCapablePhoneAccounts();
-
PreferenceScreen screen = getPreferenceScreen();
+ if (screen != null) {
+ screen.removeAll();
+ }
+
+ addPreferencesFromResource(R.xml.enable_account_preference);
+ screen = getPreferenceScreen();
+
+ List<PhoneAccountHandle> accountHandles =
+ mTelecomManager.getCallCapablePhoneAccounts(true /* includeDisabledAccounts */);
+
Context context = getActivity();
for (PhoneAccountHandle handle : accountHandles) {
PhoneAccount account = mTelecomManager.getPhoneAccount(handle);
diff --git a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
index 8674b09..c55e89c 100644
--- a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
+++ b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
@@ -131,7 +131,7 @@
.build());
assertEquals(4, mRegistrar.getAllPhoneAccountHandles().size());
- assertEquals(3, mRegistrar.getCallCapablePhoneAccounts(null).size());
+ assertEquals(3, mRegistrar.getCallCapablePhoneAccounts(null, false).size());
assertEquals(null, mRegistrar.getSimCallManager());
assertEquals(null, mRegistrar.getOutgoingPhoneAccountForScheme(PhoneAccount.SCHEME_TEL));
}