Improve Wi-Fi wiring
Bug: 16552606
Change-Id: Iddbde3d18e92ad1d40fb539d9177df582f317a7b
diff --git a/src/com/android/telecomm/AccountSelectionPreference.java b/src/com/android/telecomm/AccountSelectionPreference.java
new file mode 100644
index 0000000..e7c2bc0
--- /dev/null
+++ b/src/com/android/telecomm/AccountSelectionPreference.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telecomm;
+
+import android.content.Context;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.telecomm.PhoneAccountHandle;
+import android.util.AttributeSet;
+
+import java.util.List;
+import java.util.Objects;
+
+public class AccountSelectionPreference extends ListPreference implements
+ Preference.OnPreferenceChangeListener {
+
+ public interface AccountSelectionListener {
+ boolean onAccountSelected(AccountSelectionPreference pref, PhoneAccountHandle account);
+ }
+
+ private AccountSelectionListener mListener;
+ private PhoneAccountHandle[] mAccounts;
+ private String[] mEntryValues;
+ private CharSequence[] mEntries;
+
+ public AccountSelectionPreference(Context context) {
+ super(context);
+ setOnPreferenceChangeListener(this);
+ }
+
+ public AccountSelectionPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setOnPreferenceChangeListener(this);
+ }
+
+ public void setListener(AccountSelectionListener listener) {
+ mListener = listener;
+ }
+
+ public void setModel(
+ PhoneAccountRegistrar registrar,
+ List<PhoneAccountHandle> accountsList,
+ PhoneAccountHandle currentSelection,
+ CharSequence nullSelectionString) {
+ mAccounts = accountsList.toArray(new PhoneAccountHandle[accountsList.size()]);
+ mEntryValues = new String[mAccounts.length + 1];
+ mEntries = new CharSequence[mAccounts.length + 1];
+
+ int selectedIndex = mAccounts.length; // Points to nullSelectionString by default
+ int i = 0;
+ for ( ; i < mAccounts.length; i++) {
+ CharSequence label = registrar.getPhoneAccount(mAccounts[i]).getLabel();
+ mEntries[i] = label == null ? null : label.toString();
+ mEntryValues[i] = Integer.toString(i);
+ if (Objects.equals(currentSelection, mAccounts[i])) {
+ selectedIndex = i;
+ }
+ }
+ mEntryValues[i] = Integer.toString(i);
+ mEntries[i] = nullSelectionString;
+
+ setEntryValues(mEntryValues);
+ setEntries(mEntries);
+ setValueIndex(selectedIndex);
+ setSummary(mEntries[selectedIndex]);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (mListener != null) {
+ int index = Integer.parseInt((String) newValue);
+ PhoneAccountHandle account = index < mAccounts.length ? mAccounts[index] : null;
+ if (mListener.onAccountSelected(this, account)) {
+ setSummary(mEntries[index]);
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/com/android/telecomm/CreateConnectionProcessor.java b/src/com/android/telecomm/CreateConnectionProcessor.java
index a0cb688..0f28974 100644
--- a/src/com/android/telecomm/CreateConnectionProcessor.java
+++ b/src/com/android/telecomm/CreateConnectionProcessor.java
@@ -24,6 +24,7 @@
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Objects;
/**
* This class creates connections to place new outgoing calls to attached to an existing incoming
@@ -33,10 +34,35 @@
* - a connection service cancels the process, in which case the call is aborted
*/
final class CreateConnectionProcessor {
+
+ // Describes information required to attempt to make a phone call
+ private static class CallAttemptRecord {
+ // The PhoneAccount describing the target connection service which we will
+ // contact in order to process an attempt
+ public final PhoneAccountHandle targetConnectionServiceAccount;
+ // The PhoneAccount which we will tell the target connection service to use
+ // for attempting to make the actual phone call
+ public final PhoneAccountHandle phoneAccount;
+
+ public CallAttemptRecord(
+ PhoneAccountHandle targetConnectionServiceAccount,
+ PhoneAccountHandle phoneAccount) {
+ this.targetConnectionServiceAccount = targetConnectionServiceAccount;
+ this.phoneAccount = phoneAccount;
+ }
+
+ @Override
+ public String toString() {
+ return "CallAttemptRecord("
+ + Objects.toString(targetConnectionServiceAccount) + ","
+ + Objects.toString(phoneAccount) + ")";
+ }
+ }
+
private final Call mCall;
private final ConnectionServiceRepository mRepository;
- private List<PhoneAccountHandle> mPhoneAccountHandles;
- private Iterator<PhoneAccountHandle> mPhoneAccountHandleIterator;
+ private List<CallAttemptRecord> mAttemptRecords;
+ private Iterator<CallAttemptRecord> mAttemptRecordIterator;
private CreateConnectionResponse mResponse;
private int mLastErrorCode = DisconnectCause.OUTGOING_FAILURE;
private String mLastErrorMsg;
@@ -50,12 +76,14 @@
void process() {
Log.v(this, "process");
- mPhoneAccountHandles = new ArrayList<>();
+ mAttemptRecords = new ArrayList<>();
if (mCall.getPhoneAccount() != null) {
- mPhoneAccountHandles.add(mCall.getPhoneAccount());
+ mAttemptRecords.add(
+ new CallAttemptRecord(mCall.getPhoneAccount(), mCall.getPhoneAccount()));
}
- adjustPhoneAccountsForEmergency();
- mPhoneAccountHandleIterator = mPhoneAccountHandles.iterator();
+ adjustAttemptsForWifi();
+ adjustAttemptsForEmergency();
+ mAttemptRecordIterator = mAttemptRecords.iterator();
attemptNextPhoneAccount();
}
@@ -80,16 +108,16 @@
private void attemptNextPhoneAccount() {
Log.v(this, "attemptNextPhoneAccount");
- if (mResponse != null && mPhoneAccountHandleIterator.hasNext()) {
- PhoneAccountHandle accountHandle = mPhoneAccountHandleIterator.next();
- Log.i(this, "Trying accountHandle %s", accountHandle);
+ if (mResponse != null && mAttemptRecordIterator.hasNext()) {
+ CallAttemptRecord attempt = mAttemptRecordIterator.next();
+ Log.i(this, "Trying attempt %s", attempt);
ConnectionServiceWrapper service =
- mRepository.getService(accountHandle.getComponentName());
+ mRepository.getService(attempt.targetConnectionServiceAccount.getComponentName());
if (service == null) {
- Log.i(this, "Found no connection service for accountHandle %s", accountHandle);
+ Log.i(this, "Found no connection service for attempt %s", attempt);
attemptNextPhoneAccount();
} else {
- mCall.setPhoneAccount(accountHandle);
+ mCall.setPhoneAccount(attempt.phoneAccount);
mCall.setConnectionService(service);
Log.i(this, "Attempting to call from %s", service.getComponentName());
service.createConnection(mCall, new Response(service));
@@ -104,19 +132,45 @@
}
}
+ // If there exists a registered Wi-Fi calling service, use it.
+ private void adjustAttemptsForWifi() {
+ switch (mAttemptRecords.size()) {
+ case 0:
+ return;
+ case 1:
+ break;
+ default:
+ Log.d(this, "Unexpectedly have > 1 attempt: %s", mAttemptRecords);
+ return;
+ }
+ PhoneAccountHandle simCallManager =
+ TelecommApp.getInstance().getPhoneAccountRegistrar().getSimCallManager();
+ if (simCallManager != null &&
+ !Objects.equals(simCallManager, mAttemptRecords.get(0).phoneAccount)) {
+ mAttemptRecords.set(
+ 0,
+ new CallAttemptRecord(
+ simCallManager,
+ mAttemptRecords.get(0).phoneAccount));
+ }
+ }
+
// If we are possibly attempting to call a local emergency number, ensure that the
// plain PSTN connection services are listed, and nothing else.
- private void adjustPhoneAccountsForEmergency() {
+ private void adjustAttemptsForEmergency() {
if (TelephonyUtil.shouldProcessAsEmergency(TelecommApp.getInstance(), mCall.getHandle())) {
Log.i(this, "Emergency number detected");
- mPhoneAccountHandles.clear();
+ mAttemptRecords.clear();
List<PhoneAccountHandle> allAccountHandles = TelecommApp.getInstance()
.getPhoneAccountRegistrar().getEnabledPhoneAccounts();
for (int i = 0; i < allAccountHandles.size(); i++) {
if (TelephonyUtil.isPstnComponentName(
allAccountHandles.get(i).getComponentName())) {
Log.i(this, "Will try PSTN account %s for emergency", allAccountHandles.get(i));
- mPhoneAccountHandles.add(allAccountHandles.get(i));
+ mAttemptRecords.add(
+ new CallAttemptRecord(
+ allAccountHandles.get(i),
+ allAccountHandles.get(i)));
}
}
}
diff --git a/src/com/android/telecomm/PhoneAccountPreferencesActivity.java b/src/com/android/telecomm/PhoneAccountPreferencesActivity.java
index e4c62e7..2430f26 100644
--- a/src/com/android/telecomm/PhoneAccountPreferencesActivity.java
+++ b/src/com/android/telecomm/PhoneAccountPreferencesActivity.java
@@ -18,19 +18,17 @@
import android.app.Activity;
import android.os.Bundle;
-import android.preference.ListPreference;
-import android.preference.Preference;
import android.preference.PreferenceFragment;
+import android.telecomm.PhoneAccount;
import android.telecomm.PhoneAccountHandle;
-import java.util.HashMap;
+import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
-import java.util.Objects;
public class PhoneAccountPreferencesActivity extends Activity {
private static final String KEY_DEFAULT_OUTGOING_ACCOUNT = "default_outgoing_account";
+ private static final String KEY_SIM_CALL_MANAGER_ACCOUNT = "sim_call_manager_account";
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -39,54 +37,63 @@
}
public static class PreferencesFragment extends PreferenceFragment
- implements ListPreference.OnPreferenceChangeListener {
- private ListPreference mDefaultOutgoingAccount;
- private PhoneAccountRegistrar mRegistrar;
- private Map<String, PhoneAccountHandle> mAccountByValue = new HashMap<>();
+ implements AccountSelectionPreference.AccountSelectionListener {
+ private AccountSelectionPreference mDefaultOutgoingAccount;
+ private AccountSelectionPreference mSimCallManagerAccount;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.phone_account_preferences);
- mDefaultOutgoingAccount = (ListPreference) findPreference(KEY_DEFAULT_OUTGOING_ACCOUNT);
- mRegistrar = TelecommApp.getInstance().getPhoneAccountRegistrar();
- List<PhoneAccountHandle> accountHandles = mRegistrar.getEnabledPhoneAccounts();
- PhoneAccountHandle currentDefault = mRegistrar.getDefaultOutgoingPhoneAccount();
+ mDefaultOutgoingAccount = (AccountSelectionPreference)
+ findPreference(KEY_DEFAULT_OUTGOING_ACCOUNT);
+ mSimCallManagerAccount = (AccountSelectionPreference)
+ findPreference(KEY_SIM_CALL_MANAGER_ACCOUNT);
- String[] entryValues = new String[accountHandles.size() + 1];
- String[] entries = new String[accountHandles.size() + 1];
+ PhoneAccountRegistrar registrar = TelecommApp.getInstance().getPhoneAccountRegistrar();
- int selectedIndex = accountHandles.size(); // Points to "ask every time" by default
- int i = 0;
- for ( ; i < accountHandles.size(); i++) {
- CharSequence label = mRegistrar.getPhoneAccount(accountHandles.get(i))
- .getLabel();
- entries[i] = label == null ? null : label.toString();
- entryValues[i] = Integer.toString(i);
- if (Objects.equals(currentDefault, accountHandles.get(i))) {
- selectedIndex = i;
- }
- mAccountByValue.put(entryValues[i], accountHandles.get(i));
- }
- entryValues[i] = Integer.toString(i);
- entries[i] = getString(R.string.account_ask_every_time);
- mAccountByValue.put(entryValues[i], null);
+ mDefaultOutgoingAccount.setModel(
+ registrar,
+ registrar.getEnabledPhoneAccounts(),
+ registrar.getDefaultOutgoingPhoneAccount(),
+ getString(R.string.account_ask_every_time));
- mDefaultOutgoingAccount.setEntryValues(entryValues);
- mDefaultOutgoingAccount.setEntries(entries);
- mDefaultOutgoingAccount.setValueIndex(selectedIndex);
- mDefaultOutgoingAccount.setOnPreferenceChangeListener(this);
+ mSimCallManagerAccount.setModel(
+ registrar,
+ getSimCallManagers(registrar),
+ registrar.getSimCallManager(),
+ getString(R.string.do_not_use_sim_call_manager));
+
+ mDefaultOutgoingAccount.setListener(this);
+ mSimCallManagerAccount.setListener(this);
}
@Override
- public boolean onPreferenceChange(Preference p, Object o) {
+ public boolean onAccountSelected(
+ AccountSelectionPreference p, PhoneAccountHandle account) {
+ PhoneAccountRegistrar registrar = TelecommApp.getInstance().getPhoneAccountRegistrar();
if (p == mDefaultOutgoingAccount) {
- mRegistrar.setDefaultOutgoingPhoneAccount(mAccountByValue.get(o));
+ registrar.setDefaultOutgoingPhoneAccount(account);
+ return true;
+ } else if (p == mSimCallManagerAccount) {
+ registrar.setSimCallManager(account);
return true;
}
return false;
}
+
+ private List<PhoneAccountHandle> getSimCallManagers(PhoneAccountRegistrar registrar) {
+ List<PhoneAccountHandle> simCallManagers = new ArrayList<>();
+ List<PhoneAccountHandle> allAccounts = registrar.getAllPhoneAccountHandles();
+ for (int i = 0; i < allAccounts.size(); i++) {
+ PhoneAccount account = registrar.getPhoneAccount(allAccounts.get(i));
+ if ((account.getCapabilities() & PhoneAccount.CAPABILITY_SIM_CALL_MANAGER) != 0) {
+ simCallManagers.add(allAccounts.get(i));
+ }
+ }
+ return simCallManagers;
+ }
}
}
diff --git a/src/com/android/telecomm/PhoneAccountRegistrar.java b/src/com/android/telecomm/PhoneAccountRegistrar.java
index 4c781de..f236f58 100644
--- a/src/com/android/telecomm/PhoneAccountRegistrar.java
+++ b/src/com/android/telecomm/PhoneAccountRegistrar.java
@@ -49,50 +49,47 @@
private static final String PREFERENCE_PHONE_ACCOUNTS = "phone_accounts";
private final Context mContext;
+ private final State mState;
PhoneAccountRegistrar(Context context) {
mContext = context;
+ mState = readState();
}
public PhoneAccountHandle getDefaultOutgoingPhoneAccount() {
- State s = read();
-
- if (s.defaultOutgoingHandle != null) {
+ if (mState.defaultOutgoing != null) {
// Return the registered outgoing default iff it still exists (we keep a sticky
// default to survive account deletion and re-addition)
- for (int i = 0; i < s.accounts.size(); i++) {
- if (s.accounts.get(i).getAccountHandle().equals(s.defaultOutgoingHandle)) {
- return s.defaultOutgoingHandle;
+ for (int i = 0; i < mState.accounts.size(); i++) {
+ if (mState.accounts.get(i).getAccountHandle().equals(mState.defaultOutgoing)) {
+ return mState.defaultOutgoing;
}
}
- // At this point, there was a registered default but it has been deleted; remember
- // it for the future, but return null from this method
- return null;
- } else {
- List<PhoneAccountHandle> enabled = getEnabledPhoneAccounts();
- switch (enabled.size()) {
- case 0:
- // There are no accounts, so there can be no default
- return null;
- case 1:
- // There is only one account, which is by definition the default
- return enabled.get(0);
- default:
- // There are multiple accounts with no selected default
- return null;
- }
+ // At this point, there was a registered default but it has been deleted; proceed
+ // as though there were no default
+ }
+
+ List<PhoneAccountHandle> enabled = getEnabledPhoneAccounts();
+ switch (enabled.size()) {
+ case 0:
+ // There are no accounts, so there can be no default
+ return null;
+ case 1:
+ // There is only one account, which is by definition the default
+ return enabled.get(0);
+ default:
+ // There are multiple accounts with no selected default
+ return null;
}
}
public void setDefaultOutgoingPhoneAccount(PhoneAccountHandle accountHandle) {
- State s = read();
-
if (accountHandle == null) {
// Asking to clear the default outgoing is a valid request
- s.defaultOutgoingHandle = null;
+ mState.defaultOutgoing = null;
} else {
boolean found = false;
- for (PhoneAccount m : s.accounts) {
+ for (PhoneAccount m : mState.accounts) {
if (Objects.equals(accountHandle, m.getAccountHandle())) {
found = true;
break;
@@ -105,21 +102,51 @@
return;
}
- s.defaultOutgoingHandle = accountHandle;
+ mState.defaultOutgoing = accountHandle;
}
- write(s);
+ write();
}
+ public void setSimCallManager(PhoneAccountHandle callManager) {
+ if (callManager != null) {
+ PhoneAccount callManagerAccount = getPhoneAccount(callManager);
+ if (callManagerAccount == null) {
+ Log.d(this, "setSimCallManager: Nonexistent call manager: %s", callManager);
+ return;
+ } else if (!has(callManagerAccount, PhoneAccount.CAPABILITY_SIM_CALL_MANAGER)) {
+ Log.d(this, "setSimCallManager: Not a call manager: %s", callManagerAccount);
+ return;
+ }
+ }
+ mState.simCallManager = callManager;
+ write();
+ }
+
+ public PhoneAccountHandle getSimCallManager() {
+ return mState.simCallManager;
+ }
+
+ public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
+ List<PhoneAccountHandle> accountHandles = new ArrayList<>();
+ for (PhoneAccount m : mState.accounts) {
+ accountHandles.add(m.getAccountHandle());
+ }
+ return accountHandles;
+ }
+
+ public List<PhoneAccount> getAllPhoneAccounts() {
+ return new ArrayList<>(mState.accounts);
+ }
+
+ // TODO: Rename systemwide to "getCallProviderPhoneAccounts"?
public List<PhoneAccountHandle> getEnabledPhoneAccounts() {
- State s = read();
- return simSubscriptionAccountHandles(s);
+ return getCallProviderAccountHandles();
}
- public PhoneAccount getPhoneAccount(PhoneAccountHandle accountHandle) {
- State s = read();
- for (PhoneAccount m : s.accounts) {
- if (Objects.equals(accountHandle, m.getAccountHandle())) {
+ public PhoneAccount getPhoneAccount(PhoneAccountHandle handle) {
+ for (PhoneAccount m : mState.accounts) {
+ if (Objects.equals(handle, m.getAccountHandle())) {
return m;
}
}
@@ -128,60 +155,112 @@
// TODO: Should we implement an artificial limit for # of accounts associated with a single
// ComponentName?
- public void registerPhoneAccount(PhoneAccount metadata) {
- State s = read();
-
- s.accounts.add(metadata);
+ public void registerPhoneAccount(PhoneAccount account) {
+ account = hackFixBabelAccount(account);
+ mState.accounts.add(account);
// Search for duplicates and remove any that are found.
- for (int i = 0; i < s.accounts.size() - 1; i++) {
- if (Objects.equals(metadata.getAccountHandle(), s.accounts.get(i).getAccountHandle())) {
+ for (int i = 0; i < mState.accounts.size() - 1; i++) {
+ if (Objects.equals(
+ account.getAccountHandle(), mState.accounts.get(i).getAccountHandle())) {
// replace existing entry.
- s.accounts.remove(i);
+ mState.accounts.remove(i);
break;
}
}
- write(s);
+ write();
+ }
+
+ // STOPSHIP: Hack to edit the account registered by Babel so it shows up properly
+ private PhoneAccount hackFixBabelAccount(PhoneAccount account) {
+ String pkg = account.getAccountHandle().getComponentName().getPackageName();
+ return "com.google.android.talk".equals(pkg)
+ ? new PhoneAccount(
+ account.getAccountHandle(),
+ account.getHandle(),
+ account.getSubscriptionNumber(),
+ PhoneAccount.CAPABILITY_SIM_CALL_MANAGER,
+ account.getIconResId(),
+ account.getLabel(),
+ account.getShortDescription(),
+ account.isVideoCallingSupported())
+ : account;
}
public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
- State s = read();
-
- for (int i = 0; i < s.accounts.size(); i++) {
- if (Objects.equals(accountHandle, s.accounts.get(i).getAccountHandle())) {
- s.accounts.remove(i);
+ for (int i = 0; i < mState.accounts.size(); i++) {
+ if (Objects.equals(accountHandle, mState.accounts.get(i).getAccountHandle())) {
+ mState.accounts.remove(i);
break;
}
}
- write(s);
+ write();
}
public void clearAccounts(String packageName) {
- State s = read();
-
- for (int i = 0; i < s.accounts.size(); i++) {
+ for (int i = 0; i < mState.accounts.size(); i++) {
if (Objects.equals(
packageName,
- s.accounts.get(i).getAccountHandle().getComponentName().getPackageName())) {
- s.accounts.remove(i);
+ mState.accounts.get(i).getAccountHandle()
+ .getComponentName().getPackageName())) {
+ mState.accounts.remove(i);
}
}
- write(s);
+ write();
}
- private List<PhoneAccountHandle> simSubscriptionAccountHandles(State s) {
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+
+ // TODO: Add a corresponding has(...) method to class PhoneAccount itself and remove this one
+ // Return true iff the given account has all the specified capability flags
+ static boolean has(PhoneAccount account, int capability) {
+ return (account.getCapabilities() & capability) == capability;
+ }
+
+ private List<PhoneAccountHandle> getCallProviderAccountHandles() {
List<PhoneAccountHandle> accountHandles = new ArrayList<>();
- for (PhoneAccount m : s.accounts) {
- if ((m.getCapabilities() & PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) != 0) {
+ for (PhoneAccount m : mState.accounts) {
+ if (has(m, PhoneAccount.CAPABILITY_CALL_PROVIDER)) {
accountHandles.add(m.getAccountHandle());
}
}
return accountHandles;
}
- private State read() {
+ /**
+ * The state of this {@code PhoneAccountRegistrar}.
+ */
+ private static class State {
+ /**
+ * The account selected by the user to be employed by default for making outgoing calls.
+ * If the user has not made such a selection, then this is null.
+ */
+ public PhoneAccountHandle defaultOutgoing = null;
+
+ /**
+ * A {@code PhoneAccount} having {@link PhoneAccount#CAPABILITY_SIM_CALL_MANAGER} which
+ * manages and optimizes a user's PSTN SIM connections.
+ */
+ public PhoneAccountHandle simCallManager;
+
+ /**
+ * The complete list of {@code PhoneAccount}s known to the Telecomm subsystem.
+ */
+ public final List<PhoneAccount> accounts = new ArrayList<>();
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // State management
+ //
+
+ private void write() {
+ writeState(mState);
+ }
+
+ private State readState() {
try {
String serialized = getPreferences().getString(PREFERENCE_PHONE_ACCOUNTS, null);
Log.v(this, "read() obtained serialized state: %s", serialized);
@@ -196,7 +275,7 @@
}
}
- private boolean write(State state) {
+ private boolean writeState(State state) {
try {
Log.v(this, "write() writing state: %s", state);
String serialized = serializeState(state);
@@ -226,11 +305,7 @@
return sStateJson.fromJson(new JSONObject(new JSONTokener(s)));
}
- private static class State {
- public PhoneAccountHandle defaultOutgoingHandle = null;
- public final List<PhoneAccount> accounts = new ArrayList<>();
- }
-
+ ////////////////////////////////////////////////////////////////////////////////////////////////
//
// JSON serialization
//
@@ -243,17 +318,21 @@
private static final Json<State> sStateJson =
new Json<State>() {
private static final String DEFAULT_OUTGOING = "default_outgoing";
+ private static final String SIM_CALL_MANAGER = "sim_call_manager";
private static final String ACCOUNTS = "accounts";
@Override
public JSONObject toJson(State o) throws JSONException {
JSONObject json = new JSONObject();
- if (o.defaultOutgoingHandle != null) {
- json.put(DEFAULT_OUTGOING, sPhoneAccountJson.toJson(o.defaultOutgoingHandle));
+ if (o.defaultOutgoing != null) {
+ json.put(DEFAULT_OUTGOING, sPhoneAccountHandleJson.toJson(o.defaultOutgoing));
+ }
+ if (o.simCallManager != null) {
+ json.put(SIM_CALL_MANAGER, sPhoneAccountHandleJson.toJson(o.simCallManager));
}
JSONArray accounts = new JSONArray();
for (PhoneAccount m : o.accounts) {
- accounts.put(sPhoneAccountMetadataJson.toJson(m));
+ accounts.put(sPhoneAccountJson.toJson(m));
}
json.put(ACCOUNTS, accounts);
return json;
@@ -263,14 +342,26 @@
public State fromJson(JSONObject json) throws JSONException {
State s = new State();
if (json.has(DEFAULT_OUTGOING)) {
- s.defaultOutgoingHandle = sPhoneAccountJson.fromJson(
- (JSONObject) json.get(DEFAULT_OUTGOING));
+ try {
+ s.defaultOutgoing = sPhoneAccountHandleJson.fromJson(
+ (JSONObject) json.get(DEFAULT_OUTGOING));
+ } catch (Exception e) {
+ Log.e(this, e, "Extracting PhoneAccountHandle");
+ }
+ }
+ if (json.has(SIM_CALL_MANAGER)) {
+ try {
+ s.simCallManager = sPhoneAccountHandleJson.fromJson(
+ (JSONObject) json.get(SIM_CALL_MANAGER));
+ } catch (Exception e) {
+ Log.e(this, e, "Extracting PhoneAccountHandle");
+ }
}
if (json.has(ACCOUNTS)) {
JSONArray accounts = (JSONArray) json.get(ACCOUNTS);
for (int i = 0; i < accounts.length(); i++) {
try {
- s.accounts.add(sPhoneAccountMetadataJson.fromJson(
+ s.accounts.add(sPhoneAccountJson.fromJson(
(JSONObject) accounts.get(i)));
} catch (Exception e) {
Log.e(this, e, "Extracting phone account");
@@ -281,7 +372,7 @@
}
};
- private static final Json<PhoneAccount> sPhoneAccountMetadataJson =
+ private static final Json<PhoneAccount> sPhoneAccountJson =
new Json<PhoneAccount>() {
private static final String ACCOUNT = "account";
private static final String HANDLE = "handle";
@@ -295,7 +386,7 @@
@Override
public JSONObject toJson(PhoneAccount o) throws JSONException {
return new JSONObject()
- .put(ACCOUNT, sPhoneAccountJson.toJson(o.getAccountHandle()))
+ .put(ACCOUNT, sPhoneAccountHandleJson.toJson(o.getAccountHandle()))
.put(HANDLE, o.getHandle().toString())
.put(SUBSCRIPTION_NUMBER, o.getSubscriptionNumber())
.put(CAPABILITIES, o.getCapabilities())
@@ -308,7 +399,7 @@
@Override
public PhoneAccount fromJson(JSONObject json) throws JSONException {
return new PhoneAccount(
- sPhoneAccountJson.fromJson((JSONObject) json.get(ACCOUNT)),
+ sPhoneAccountHandleJson.fromJson((JSONObject) json.get(ACCOUNT)),
Uri.parse((String) json.get(HANDLE)),
(String) json.get(SUBSCRIPTION_NUMBER),
(int) json.get(CAPABILITIES),
@@ -319,7 +410,7 @@
}
};
- private static final Json<PhoneAccountHandle> sPhoneAccountJson =
+ private static final Json<PhoneAccountHandle> sPhoneAccountHandleJson =
new Json<PhoneAccountHandle>() {
private static final String COMPONENT_NAME = "component_name";
private static final String ID = "id";
diff --git a/src/com/android/telecomm/TelecommServiceImpl.java b/src/com/android/telecomm/TelecommServiceImpl.java
index b0fc709..3598422 100644
--- a/src/com/android/telecomm/TelecommServiceImpl.java
+++ b/src/com/android/telecomm/TelecommServiceImpl.java
@@ -193,7 +193,8 @@
try {
enforceModifyPermissionOrCallingPackage(
account.getAccountHandle().getComponentName().getPackageName());
- if ((account.getCapabilities() & PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) != 0) {
+ if (PhoneAccountRegistrar.has(account, PhoneAccount.CAPABILITY_CALL_PROVIDER) ||
+ PhoneAccountRegistrar.has(account, PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
enforceModifyPermissionOrCallingPackage(TELEPHONY_PACKAGE_NAME);
}
mPhoneAccountRegistrar.registerPhoneAccount(account);