Register PhoneAccounts for telephony on startup.
Change-Id: I597a0565696a742540ba7156f17d6b1d188d7eb7
diff --git a/src/com/android/phone/PhoneSearchIndexablesProvider.java b/src/com/android/phone/PhoneSearchIndexablesProvider.java
index 4b2476c..f1dacd9 100644
--- a/src/com/android/phone/PhoneSearchIndexablesProvider.java
+++ b/src/com/android/phone/PhoneSearchIndexablesProvider.java
@@ -75,4 +75,4 @@
MatrixCursor cursor = new MatrixCursor(NON_INDEXABLES_KEYS_COLUMNS);
return cursor;
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/services/telephony/AddAccountsReceiver.java b/src/com/android/services/telephony/AddAccountsReceiver.java
index 2e635c7..f106e7d 100644
--- a/src/com/android/services/telephony/AddAccountsReceiver.java
+++ b/src/com/android/services/telephony/AddAccountsReceiver.java
@@ -16,58 +16,17 @@
package com.android.services.telephony;
-import com.android.phone.R;
-
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.net.Uri;
-import android.telecomm.PhoneAccount;
-import android.telecomm.PhoneAccountMetadata;
-import android.telecomm.TelecommManager;
public class AddAccountsReceiver extends BroadcastReceiver {
-
- private static String SCHEME_TEL = "tel";
-
@Override
public void onReceive(Context context, Intent intent) {
- Log.d(this, "onReceive");
- try {
- TelecommManager telecommManager = TelecommManager.from(context);
- telecommManager.clearAccounts(context.getPackageName());
- PhoneAccountMetadata[] accounts = makeAccounts(context);
- for (int i = 0; i < accounts.length; i++) {
- telecommManager.registerPhoneAccount(accounts[i]);
- }
- } catch (Exception e) {
- Log.e(this, e, "onReceive");
- throw e;
+ String action = intent.getAction();
+ Log.d(this, "onReceive(%s)", action);
+ if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
+ TelecommAccountRegistry.getInstance(context).setup();
}
}
-
- public static PhoneAccountMetadata[] makeAccounts(Context context) {
- ComponentName componentName = new ComponentName(
- context.getPackageName(),
- TelephonyConnectionService.class.getName());
- return new PhoneAccountMetadata[]{
- new PhoneAccountMetadata(
- new PhoneAccount(componentName, "sim_0"),
- Uri.fromParts(SCHEME_TEL, "650-555-1212", null),
- PhoneAccountMetadata.CAPABILITY_CALL_PROVIDER,
- R.drawable.fab_ic_call,
- "Zero SIM Account",
- "Short description for SIM card zero",
- false),
- new PhoneAccountMetadata(
- new PhoneAccount(componentName, "sim_1"),
- Uri.fromParts(SCHEME_TEL, "650-555-1234", null),
- PhoneAccountMetadata.CAPABILITY_CALL_PROVIDER,
- R.drawable.fab_ic_call,
- "One SIM Account",
- "Short description for SIM card one",
- false)
- };
- }
}
diff --git a/src/com/android/services/telephony/PstnIncomingCallNotifier.java b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
index 1ba4a4e..b24758f 100644
--- a/src/com/android/services/telephony/PstnIncomingCallNotifier.java
+++ b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
@@ -17,6 +17,8 @@
package com.android.services.telephony;
import android.content.BroadcastReceiver;
+
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -24,6 +26,7 @@
import android.os.Handler;
import android.os.Message;
import android.os.UserHandle;
+import android.telecomm.PhoneAccount;
import android.telecomm.TelecommConstants;
import com.android.internal.telephony.Call;
@@ -156,7 +159,7 @@
Intent intent = new Intent(TelecommConstants.ACTION_INCOMING_CALL);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(TelecommConstants.EXTRA_PHONE_ACCOUNT,
- AddAccountsReceiver.makeAccounts(context)[0].getAccount());
+ TelecommAccountRegistry.makePstnPhoneAccount(mPhoneProxy));
Log.d(this, "Sending incoming call intent: %s", intent);
context.startActivityAsUser(intent, UserHandle.CURRENT);
diff --git a/src/com/android/services/telephony/TelecommAccountRegistry.java b/src/com/android/services/telephony/TelecommAccountRegistry.java
new file mode 100644
index 0000000..ac8bb91
--- /dev/null
+++ b/src/com/android/services/telephony/TelecommAccountRegistry.java
@@ -0,0 +1,135 @@
+/*
+ * 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.services.telephony;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.net.Uri;
+import android.telecomm.PhoneAccount;
+import android.telecomm.PhoneAccountMetadata;
+import android.telecomm.TelecommManager;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.PhoneProxy;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Owns all data we have registered with Telecomm including handling dynamic addition and
+ * removal of SIMs and SIP accounts.
+ */
+final class TelecommAccountRegistry {
+ private final class AccountEntry {
+ private final Phone mPhone;
+ private final PhoneAccountMetadata mMetadata;
+ private final PstnIncomingCallNotifier mIncomingCallNotifier;
+
+ AccountEntry(Phone phone, boolean isDummy) {
+ mPhone = phone;
+ mMetadata = registerPstnPhoneAccount(isDummy);
+ mIncomingCallNotifier = new PstnIncomingCallNotifier((PhoneProxy) mPhone);
+ }
+
+ /**
+ * Registers the specified account with Telecomm as a PhoneAccount.
+ */
+ private PhoneAccountMetadata registerPstnPhoneAccount(boolean isDummyAccount) {
+ TelephonyManager telephonyManager = TelephonyManager.from(mContext);
+ String dummyPrefix = isDummyAccount ? "Dummy " : "";
+
+ // Build the Phone account handle.
+ PhoneAccount phoneAccount = isDummyAccount ?
+ makePstnPhoneAccountWithPrefix(mPhone, dummyPrefix) :
+ makePstnPhoneAccount(mPhone);
+
+ // Populate the phone account data.
+ long subId = mPhone.getSubId();
+ int slotId = mPhone.getPhoneId() + 1;
+ PhoneAccountMetadata metadata = new PhoneAccountMetadata(
+ phoneAccount,
+ Uri.fromParts(TEL_SCHEME, telephonyManager.getLine1Number(subId), null),
+ PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
+ PhoneAccountMetadata.CAPABILITY_CALL_PROVIDER,
+ com.android.phone.R.mipmap.ic_launcher_phone,
+ dummyPrefix + "SIM " + slotId,
+ dummyPrefix + "SIM card in slot " + slotId,
+ true /* supportsVideoCalling */);
+
+ // Register with Telecomm and put into the account entry.
+ mTelecommManager.registerPhoneAccount(metadata);
+ return metadata;
+ }
+ }
+
+ private static final String TEL_SCHEME = "tel";
+ private static TelecommAccountRegistry sInstance;
+ private final Context mContext;
+ private final TelecommManager mTelecommManager;
+ private List<AccountEntry> mAccounts = new LinkedList<AccountEntry>();
+
+ TelecommAccountRegistry(Context context) {
+ mContext = context;
+ mTelecommManager = TelecommManager.from(context);
+ }
+
+ static synchronized final TelecommAccountRegistry getInstance(Context context) {
+ if (sInstance == null) {
+ sInstance = new TelecommAccountRegistry(context);
+ }
+ return sInstance;
+ }
+
+ /**
+ * Sets up all the phone accounts for SIM and SIP accounts on first boot.
+ */
+ void setup() {
+ // Before we do anything, we need to clear whatever entries we registered at boot.
+ mTelecommManager.clearAccounts(mContext.getPackageName());
+
+ // Go through SIM-based phones and register ourselves
+ Phone[] phones = PhoneFactory.getPhones();
+ Log.d(this, "Found %d phones. Attempting to register.", phones.length);
+ for (Phone phone : phones) {
+ long subscriptionId = phone.getSubId();
+ Log.d(this, "Phone with subscription id %d", subscriptionId);
+ if (subscriptionId >= 0) {
+ mAccounts.add(new AccountEntry(phone, false /* isDummy */));
+ }
+ }
+
+ // Add a fake account entry.
+ if (phones.length > 0 && "TRUE".equals(System.getProperty("dummy_sim"))) {
+ mAccounts.add(new AccountEntry(phones[0], true /* isDummy */));
+ }
+
+ // TODO: Add SIP accounts.
+ }
+
+ static PhoneAccount makePstnPhoneAccount(Phone phone) {
+ return makePstnPhoneAccountWithPrefix(phone, "");
+ }
+
+ private static PhoneAccount makePstnPhoneAccountWithPrefix(Phone phone, String prefix) {
+ ComponentName pstnConnectionServiceName =
+ new ComponentName(phone.getContext(), TelephonyConnectionService.class);
+ return new PhoneAccount(
+ pstnConnectionServiceName, prefix + String.valueOf(phone.getSubId()));
+ }
+}
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index bf2e3a0..0572d49 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -17,27 +17,26 @@
package com.android.services.telephony;
import android.content.ComponentName;
-import android.content.Context;
import android.net.Uri;
-import android.os.Debug;
-import android.telecomm.PhoneAccountMetadata;
-import android.telecomm.TelecommManager;
-import android.telephony.DisconnectCause;
-import android.telephony.ServiceState;
-import android.text.TextUtils;
import android.telecomm.CallCapabilities;
import android.telecomm.Connection;
import android.telecomm.ConnectionRequest;
import android.telecomm.ConnectionService;
import android.telecomm.PhoneAccount;
import android.telecomm.Response;
+import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
+import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.SubscriptionController;
+
+import java.util.Objects;
/**
* Service for making GSM and CDMA connections.
@@ -45,9 +44,16 @@
public class TelephonyConnectionService extends ConnectionService {
private static String SCHEME_TEL = "tel";
+ private ComponentName mExpectedComponentName = null;
private EmergencyCallHelper mEmergencyCallHelper;
@Override
+ public void onCreate() {
+ super.onCreate();
+ mExpectedComponentName = new ComponentName(this, this.getClass());
+ }
+
+ @Override
protected void onCreateOutgoingConnection(
final ConnectionRequest request,
final CreateConnectionResponse<Connection> response) {
@@ -75,7 +81,8 @@
return;
}
- final Phone phone = PhoneFactory.getDefaultPhone();
+ // Get the right phone object from the account data passed in.
+ final Phone phone = getPhoneForAccount(request.getAccount());
if (phone == null) {
Log.d(this, "onCreateOutgoingConnection, phone is null");
response.onFailure(request, DisconnectCause.ERROR_UNSPECIFIED, "Phone is null");
@@ -153,7 +160,12 @@
CreateConnectionResponse<Connection> response) {
Log.v(this, "onCreateIncomingConnection, request: " + request);
- Phone phone = PhoneFactory.getDefaultPhone();
+ Phone phone = getPhoneForAccount(request.getAccount());
+ if (phone == null) {
+ response.onFailure(request, DisconnectCause.ERROR_UNSPECIFIED, null);
+ return;
+ }
+
Call call = phone.getRingingCall();
if (!call.getState().isRinging()) {
Log.v(this, "onCreateIncomingConnection, no ringing call");
@@ -261,6 +273,15 @@
return false;
}
+ private Phone getPhoneForAccount(PhoneAccount account) {
+ if (Objects.equals(mExpectedComponentName, account.getComponentName())) {
+ int phoneId = SubscriptionController.getInstance().getPhoneId(
+ Long.parseLong(account.getId()));
+ return PhoneFactory.getPhone(phoneId);
+ }
+ return null;
+ }
+
static Uri getHandleFromAddress(String address) {
// Address can be null for blocked calls.
if (address == null) {
diff --git a/src/com/android/services/telephony/TelephonyGlobals.java b/src/com/android/services/telephony/TelephonyGlobals.java
index daf370b..daeece6 100644
--- a/src/com/android/services/telephony/TelephonyGlobals.java
+++ b/src/com/android/services/telephony/TelephonyGlobals.java
@@ -32,12 +32,11 @@
* {@link #onCreate}.
*/
public class TelephonyGlobals {
+ private static TelephonyGlobals sInstance;
+
/** The application context. */
private final Context mContext;
- /** Handles incoming calls for PSTN calls. */
- private PstnIncomingCallNotifier mPtsnIncomingCallNotifier;
-
private TtyManager mTtyManager;
/**
@@ -49,23 +48,18 @@
mContext = context.getApplicationContext();
}
- public void onCreate() {
- setupIncomingCallNotifiers();
+ public static synchronized TelephonyGlobals getInstance(Context context) {
+ if (sInstance == null) {
+ sInstance = new TelephonyGlobals(context);
+ }
+ return sInstance;
+ }
+ public void onCreate() {
+ // TODO: Make this work with Multi-SIM devices
Phone phone = PhoneFactory.getDefaultPhone();
if (phone != null) {
mTtyManager = new TtyManager(mContext, phone);
}
}
-
- /**
- * Sets up incoming call notifiers for all the connection services.
- */
- private void setupIncomingCallNotifiers() {
- PhoneProxy defaultPhone = (PhoneProxy) PhoneFactory.getDefaultPhone();
- Log.i(this, "Default phone: %s.", defaultPhone);
-
- Log.i(this, "Registering the PSTN listener.");
- mPtsnIncomingCallNotifier = new PstnIncomingCallNotifier(defaultPhone);
- }
}