Merge "Revert "Revert "Add color to PhoneAccount objects (2/3)""" into lmp-sprout-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 3877edf..5d11fb3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -36,6 +36,7 @@
     <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" />
 
     <!-- Protects the ability to register any PhoneAccount with a capability flags of either
          PhoneAccount#CAPABILITY_CALL_PROVIDER or PhoneAccount#CAPABILITY_SIM_SUBSCRIPTION. -->
@@ -44,6 +45,16 @@
             android:label="Register CALL_PROVIDER or SIM_SUBSCRIPTION PhoneAccount"
             android:protectionLevel="signature"/>
 
+    <permission
+            android:name="android.permission.BROADCAST_CALLLOG_INFO"
+            android:label="Broadcast the call type/duration information"
+            android:protectionLevel="signature|system"/>
+
+    <permission
+            android:name="android.permission.PROCESS_CALLLOG_INFO"
+            android:label="Register to handle the broadcasted call type/duration information"
+            android:protectionLevel="signature|system"/>
+
     <!-- Declare which SDK level this application was built against. This is needed so that IDEs
          can check for incompatible APIs. -->
     <uses-sdk android:minSdkVersion="19" />
diff --git a/src/com/android/server/telecom/BluetoothPhoneService.java b/src/com/android/server/telecom/BluetoothPhoneService.java
index 43be93a..51dbbdf 100644
--- a/src/com/android/server/telecom/BluetoothPhoneService.java
+++ b/src/com/android/server/telecom/BluetoothPhoneService.java
@@ -103,6 +103,7 @@
     private int mBluetoothCallState = CALL_STATE_IDLE;
     private String mRingingAddress = null;
     private int mRingingAddressType = 0;
+    private Call mOldHeldCall = null;
 
     /**
      * Binder implementation of IBluetoothHeadsetPhone. Implements the command interface that the
@@ -643,7 +644,7 @@
         }
 
         int numActiveCalls = activeCall == null ? 0 : 1;
-        int numHeldCalls = heldCall == null ? 0 : 1;
+        int numHeldCalls = callsManager.getNumHeldCalls();
 
         // For conference calls which support swapping the active call within the conference
         // (namely CDMA calls) we need to expose that as a held call in order for the BT device
@@ -664,6 +665,7 @@
                  bluetoothCallState != mBluetoothCallState ||
                  !TextUtils.equals(ringingAddress, mRingingAddress) ||
                  ringingAddressType != mRingingAddressType ||
+                 heldCall != mOldHeldCall ||
                  force)) {
 
             // If the call is transitioning into the alerting state, send DIALING first.
@@ -672,6 +674,7 @@
             boolean sendDialingFirst = mBluetoothCallState != bluetoothCallState &&
                     bluetoothCallState == CALL_STATE_ALERTING;
 
+            mOldHeldCall = heldCall;
             mNumActiveCalls = numActiveCalls;
             mNumHeldCalls = numHeldCalls;
             mBluetoothCallState = bluetoothCallState;
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 5e66850..a0a8a62 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -557,8 +557,12 @@
     }
 
     void setCallCapabilities(int callCapabilities) {
+        setCallCapabilities(callCapabilities, false /* forceUpdate */);
+    }
+
+    void setCallCapabilities(int callCapabilities, boolean forceUpdate) {
         Log.v(this, "setCallCapabilities: %s", PhoneCapabilities.toString(callCapabilities));
-        if (mCallCapabilities != callCapabilities) {
+        if (forceUpdate || mCallCapabilities != callCapabilities) {
            mCallCapabilities = callCapabilities;
             for (Listener l : mListeners) {
                 l.onCallCapabilitiesChanged(this);
@@ -781,7 +785,7 @@
             mCreateConnectionProcessor.abort();
         } else if (mState == CallState.NEW || mState == CallState.PRE_DIAL_WAIT
                 || mState == CallState.CONNECTING) {
-            handleCreateConnectionFailure(new DisconnectCause(DisconnectCause.LOCAL));
+            handleCreateConnectionFailure(new DisconnectCause(DisconnectCause.CANCELED));
         } else {
             Log.v(this, "Cannot abort a call which isn't either PRE_DIAL_WAIT or CONNECTING");
         }
diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java
index 1e305e2..a89dcea 100644
--- a/src/com/android/server/telecom/CallAudioManager.java
+++ b/src/com/android/server/telecom/CallAudioManager.java
@@ -330,7 +330,7 @@
     }
 
     private void updateAudioStreamAndMode() {
-        Log.v(this, "updateAudioStreamAndMode, mIsRinging: %b, mIsTonePlaying: %b", mIsRinging,
+        Log.i(this, "updateAudioStreamAndMode, mIsRinging: %b, mIsTonePlaying: %b", mIsRinging,
                 mIsTonePlaying);
         if (mIsRinging) {
             requestAudioFocusAndSetMode(AudioManager.STREAM_RING, AudioManager.MODE_RINGTONE);
@@ -359,7 +359,7 @@
     }
 
     private void requestAudioFocusAndSetMode(int stream, int mode) {
-        Log.v(this, "requestAudioFocusAndSetMode, stream: %d -> %d", mAudioFocusStreamType, stream);
+        Log.i(this, "requestAudioFocusAndSetMode, stream: %d -> %d", mAudioFocusStreamType, stream);
         Preconditions.checkState(stream != STREAM_NONE);
 
         // Even if we already have focus, if the stream is different we update audio manager to give
@@ -392,7 +392,12 @@
         Preconditions.checkState(hasFocus());
         int oldMode = mAudioManager.getMode();
         Log.v(this, "Request to change audio mode from %d to %d", oldMode, newMode);
+
         if (oldMode != newMode) {
+            if (oldMode == AudioManager.MODE_IN_CALL && newMode == AudioManager.MODE_RINGTONE) {
+                Log.i(this, "Transition from IN_CALL -> RINGTONE. Resetting to NORMAL first.");
+                mAudioManager.setMode(AudioManager.MODE_NORMAL);
+            }
             mAudioManager.setMode(newMode);
             mMostRecentlyUsedMode = newMode;
         }
diff --git a/src/com/android/server/telecom/CallLogManager.java b/src/com/android/server/telecom/CallLogManager.java
old mode 100644
new mode 100755
index 89d9316..658af10
--- a/src/com/android/server/telecom/CallLogManager.java
+++ b/src/com/android/server/telecom/CallLogManager.java
@@ -17,6 +17,8 @@
 package com.android.server.telecom;
 
 import android.content.Context;
+import android.content.Intent;
+import android.Manifest.permission;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.provider.CallLog.Calls;
@@ -83,6 +85,12 @@
     private static final String TAG = CallLogManager.class.getSimpleName();
 
     private final Context mContext;
+    private static final String ACTION_CALLS_TABLE_ADD_ENTRY =
+                "com.android.server.telecom.intent.action.CALLS_ADD_ENTRY";
+    private static final String PERMISSION_PROCESS_CALLLOG_INFO =
+                "android.permission.PROCESS_CALLLOG_INFO";
+    private static final String CALL_TYPE = "callType";
+    private static final String CALL_DURATION = "duration";
 
     public CallLogManager(Context context) {
         mContext = context;
@@ -174,6 +182,8 @@
         // Don't log emergency numbers if the device doesn't allow it.
         final boolean isOkToLogThisCall = !isEmergencyNumber || okToLogEmergencyNumber;
 
+        sendAddCallBroadcast(callType, duration);
+
         if (isOkToLogThisCall) {
             Log.d(TAG, "Logging Calllog entry: " + callerInfo + ", "
                     + Log.pii(number) + "," + presentation + ", " + callType
@@ -293,4 +303,11 @@
             }
         }
     }
+
+    private void sendAddCallBroadcast(int callType, long duration) {
+        Intent callAddIntent = new Intent(ACTION_CALLS_TABLE_ADD_ENTRY);
+        callAddIntent.putExtra(CALL_TYPE, callType);
+        callAddIntent.putExtra(CALL_DURATION, duration);
+        mContext.sendBroadcast(callAddIntent, PERMISSION_PROCESS_CALLLOG_INFO);
+    }
 }
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index de53c05..e07b279 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -17,6 +17,9 @@
 package com.android.server.telecom;
 
 import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.CallLog.Calls;
@@ -433,7 +436,10 @@
             return null;
         }
 
-        if (phoneAccountHandle == null && accounts.size() > 1 && !isEmergencyCall) {
+        boolean needsAccountSelection = phoneAccountHandle == null && accounts.size() > 1 &&
+                !isEmergencyCall;
+
+        if (needsAccountSelection) {
             // This is the state where the user is expected to select an account
             call.setState(CallState.PRE_DIAL_WAIT);
             extras.putParcelableList(android.telecom.Call.AVAILABLE_PHONE_ACCOUNTS, accounts);
@@ -443,7 +449,8 @@
 
         call.setExtras(extras);
 
-        if (isPotentialMMICode(handle) || isPotentialInCallMMICode) {
+        // Do not add the call if it is a potential MMI code.
+        if ((isPotentialMMICode(handle) || isPotentialInCallMMICode) && !needsAccountSelection) {
             call.addListener(this);
         } else {
             addCall(call);
@@ -692,7 +699,7 @@
         mProximitySensorManager.turnOff(screenOnImmediately);
     }
 
-    void phoneAccountSelected(Call call, PhoneAccountHandle account) {
+    void phoneAccountSelected(Call call, PhoneAccountHandle account, boolean setDefault) {
         if (!mCalls.contains(call)) {
             Log.i(this, "Attempted to add account to unknown call %s", call);
         } else {
@@ -711,6 +718,10 @@
             } else {
                 call.disconnect();
             }
+
+            if (setDefault) {
+                mPhoneAccountRegistrar.setUserSelectedOutgoingPhoneAccount(account);
+            }
         }
     }
 
@@ -868,6 +879,16 @@
         return getFirstCallWithState(CallState.ON_HOLD);
     }
 
+    int getNumHeldCalls() {
+        int count = 0;
+        for (Call call : mCalls) {
+            if (call.getParentCall() == null && call.getState() == CallState.ON_HOLD) {
+                count++;
+            }
+        }
+        return count;
+    }
+
     Call getFirstCallWithState(int... states) {
         return getFirstCallWithState(null, states);
     }
@@ -992,6 +1013,14 @@
             }
             updateForegroundCall();
         }
+
+        // Now that a call has been removed, other calls may gain new call capabilities (for
+        // example, if only one call is left, it is now add-call capable again). Trigger the
+        // recalculation of the call's current capabilities by forcing an update. (See
+        // InCallController.toParcelableCall()).
+        for (Call otherCall : mCalls) {
+            otherCall.setCallCapabilities(otherCall.getCallCapabilities(), true /* forceUpdate */);
+        }
     }
 
     /**
diff --git a/src/com/android/server/telecom/CreateConnectionProcessor.java b/src/com/android/server/telecom/CreateConnectionProcessor.java
index 0c6e25d..fab2679 100644
--- a/src/com/android/server/telecom/CreateConnectionProcessor.java
+++ b/src/com/android/server/telecom/CreateConnectionProcessor.java
@@ -238,6 +238,18 @@
             Log.i(this, "Emergency number detected");
             mAttemptRecords.clear();
             List<PhoneAccount> allAccounts = mPhoneAccountRegistrar.getAllPhoneAccounts();
+
+            if (allAccounts.isEmpty()) {
+                // If the list of phone accounts is empty at this point, it means Telephony hasn't
+                // registered any phone accounts yet. Add a fallback emergency phone account so
+                // that emergency calls can still go through. We create a new ArrayLists here just
+                // in case the implementation of PhoneAccountRegistrar ever returns an unmodifiable
+                // list.
+                allAccounts = new ArrayList<PhoneAccount>();
+                allAccounts.add(TelephonyUtil.getDefaultEmergencyPhoneAccount());
+            }
+
+
             // First, add SIM phone accounts which can place emergency calls.
             for (PhoneAccount phoneAccount : allAccounts) {
                 if (phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS) &&
diff --git a/src/com/android/server/telecom/InCallAdapter.java b/src/com/android/server/telecom/InCallAdapter.java
index 5a93464..d4af791 100644
--- a/src/com/android/server/telecom/InCallAdapter.java
+++ b/src/com/android/server/telecom/InCallAdapter.java
@@ -139,7 +139,8 @@
                     try {
                         call = mCallIdMapper.getCall(args.arg1);
                         if (call != null) {
-                            mCallsManager.phoneAccountSelected(call, (PhoneAccountHandle) args.arg2);
+                            mCallsManager.phoneAccountSelected(call,
+                                    (PhoneAccountHandle) args.arg2, args.argi1 == 1);
                         } else {
                             Log.w(this, "phoneAccountSelected, unknown call id: %s", args.arg1);
                         }
@@ -284,11 +285,13 @@
     }
 
     @Override
-    public void phoneAccountSelected(String callId, PhoneAccountHandle accountHandle) {
+    public void phoneAccountSelected(String callId, PhoneAccountHandle accountHandle,
+            boolean setDefault) {
         if (mCallIdMapper.isValidCallId(callId)) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = callId;
             args.arg2 = accountHandle;
+            args.argi1 = setDefault? 1 : 0;
             mHandler.obtainMessage(MSG_PHONE_ACCOUNT_SELECTED, args).sendToTarget();
         }
     }
diff --git a/src/com/android/server/telecom/InCallTonePlayer.java b/src/com/android/server/telecom/InCallTonePlayer.java
index 2ffe599..5afc67f 100644
--- a/src/com/android/server/telecom/InCallTonePlayer.java
+++ b/src/com/android/server/telecom/InCallTonePlayer.java
@@ -121,7 +121,7 @@
                 case TONE_CALL_ENDED:
                     toneType = ToneGenerator.TONE_PROP_PROMPT;
                     toneVolume = RELATIVE_VOLUME_HIPRI;
-                    toneLengthMillis = 4000;
+                    toneLengthMillis = 200;
                     break;
                 case TONE_OTA_CALL_ENDED:
                     // TODO: fill in
@@ -159,7 +159,7 @@
                 case TONE_REORDER:
                     toneType = ToneGenerator.TONE_CDMA_REORDER;
                     toneVolume = RELATIVE_VOLUME_HIPRI;
-                    toneLengthMillis = 5000;
+                    toneLengthMillis = 4000;
                     break;
                 case TONE_RING_BACK:
                     toneType = ToneGenerator.TONE_SUP_RINGTONE;
diff --git a/src/com/android/server/telecom/MissedCallNotifier.java b/src/com/android/server/telecom/MissedCallNotifier.java
index 8abd5b7..2c1ffb8 100644
--- a/src/com/android/server/telecom/MissedCallNotifier.java
+++ b/src/com/android/server/telecom/MissedCallNotifier.java
@@ -29,10 +29,13 @@
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.UserHandle;
 import android.provider.CallLog;
 import android.provider.CallLog.Calls;
 import android.telecom.CallState;
 import android.telecom.DisconnectCause;
+import android.telecom.PhoneAccount;
+import android.telephony.PhoneNumberUtils;
 import android.text.BidiFormatter;
 import android.text.TextDirectionHeuristics;
 import android.text.TextUtils;
@@ -166,7 +169,8 @@
         configureLedOnNotification(notification);
 
         Log.i(this, "Adding missed call notification for %s.", call);
-        mNotificationManager.notify(MISSED_CALL_NOTIFICATION_ID, notification);
+        mNotificationManager.notifyAsUser(
+                null /* tag */ , MISSED_CALL_NOTIFICATION_ID, notification, UserHandle.CURRENT);
     }
 
     /** Cancels the "missed call" notification. */
@@ -276,13 +280,19 @@
                     try {
                         while (cursor.moveToNext()) {
                             // Get data about the missed call from the cursor
-                            Uri handle = Uri.parse(cursor.getString(
-                                    cursor.getColumnIndexOrThrow(Calls.NUMBER)));
-                            int presentation = cursor.getInt(cursor.getColumnIndexOrThrow(
+                            final String handleString = cursor.getString(
+                                    cursor.getColumnIndexOrThrow(Calls.NUMBER));
+                            final int presentation = cursor.getInt(cursor.getColumnIndexOrThrow(
                                     Calls.NUMBER_PRESENTATION));
 
-                            if (presentation != Calls.PRESENTATION_ALLOWED) {
+                            final Uri handle;
+                            if (presentation != Calls.PRESENTATION_ALLOWED
+                                    || TextUtils.isEmpty(handleString)) {
                                 handle = null;
+                            } else {
+                                handle = Uri.fromParts(PhoneNumberUtils.isUriNumber(handleString) ?
+                                        PhoneAccount.SCHEME_SIP : PhoneAccount.SCHEME_TEL,
+                                                handleString, null);
                             }
 
                             // Convert the data to a call object
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index ecd459a..4ee2c88 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -28,6 +28,7 @@
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
+import android.telephony.PhoneNumberUtils;
 import android.content.ComponentName;
 import android.content.Context;
 import android.net.Uri;
@@ -114,6 +115,36 @@
     }
 
     /**
+     * Retrieves the phone account id for a given subscription id if it exists. Subscription ids
+     * apply only to PSTN/SIM card phone accounts so all other accounts should not have a
+     * subscription id.
+     * @param subscriptionId The subscription id for which to construct the phone account id
+     * @return The string representing the phone account id for the subscription id.
+     */
+    public String getPhoneAccountIdForSubscriptionId(long subscriptionId) {
+        return String.valueOf(subscriptionId);
+    }
+
+    /**
+     * Retrieves the subscription id for a given phone account if it exists. Subscription ids
+     * apply only to PSTN/SIM card phone accounts so all other accounts should not have a
+     * subscription id.
+     * @param accountHandle The handle for the phone account for which to retrieve the
+     * subscription id.
+     * @return The value of the subscription id (long) or -1 if it does not exist or is not valid.
+     */
+    public long getSubscriptionIdForPhoneAccount(PhoneAccountHandle accountHandle) {
+        PhoneAccount account = getPhoneAccount(accountHandle);
+        if (account == null || !account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) ||
+                !TextUtils.isDigitsOnly(accountHandle.getId())) {
+            // Since no decimals or negative numbers can be valid subscription ids, only a string of
+            // numbers can be subscription id
+            return -1;
+        }
+        return Long.parseLong(accountHandle.getId());
+    }
+
+    /**
      * Retrieves the default outgoing phone account supporting the specified uriScheme.
      * @param uriScheme The URI scheme for the outgoing call.
      * @return The {@link PhoneAccountHandle} to use.
@@ -413,6 +444,11 @@
         }
     }
 
+    public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number) {
+        long subId = getSubscriptionIdForPhoneAccount(accountHandle);
+        return PhoneNumberUtils.isVoiceMailNumber(subId, number);
+    }
+
     public void addListener(Listener l) {
         mListeners.add(l);
     }
diff --git a/src/com/android/server/telecom/Ringer.java b/src/com/android/server/telecom/Ringer.java
index cf65a11..5945306 100644
--- a/src/com/android/server/telecom/Ringer.java
+++ b/src/com/android/server/telecom/Ringer.java
@@ -140,12 +140,8 @@
     private void onRespondedToIncomingCall(Call call) {
         // Only stop the ringer if this call is the top-most incoming call.
         if (getTopMostUnansweredCall() == call) {
-            stopRinging();
-            stopCallWaiting();
+            removeFromUnansweredCall(call);
         }
-
-        // We do not remove the call from mRingingCalls until the call state changes from
-        // STATE_RINGING or the call is removed. see onCallStateChanged or onCallRemoved.
     }
 
     private Call getTopMostUnansweredCall() {
@@ -203,7 +199,11 @@
                         VIBRATION_ATTRIBUTES);
                 mIsVibrating = true;
             }
-        } else {
+        } else if (foregroundCall != null) {
+            // The first incoming call added to Telecom is not a foreground call at this point
+            // in time. If the current foreground call is null at point, don't play call-waiting
+            // as the call will eventually be promoted to the foreground call and play the
+            // ring tone.
             Log.v(this, "Playing call-waiting tone.");
 
             // All incoming calls are in background so play call waiting.
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index fbbe1c9..3af67d8 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -35,9 +35,9 @@
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
+import android.telephony.PhoneNumberUtils;
 import android.telephony.TelephonyManager;
 
-
 // TODO: Needed for move to system service: import com.android.internal.R;
 import com.android.internal.telecom.ITelecomService;
 import com.android.internal.util.IndentingPrintWriter;
@@ -327,6 +327,20 @@
     }
 
     /**
+     * @see android.telecom.TelecomManager#isVoiceMailNumber
+     */
+    @Override
+    public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number) {
+        enforceReadPermissionOrDefaultDialer();
+        try {
+            return mPhoneAccountRegistrar.isVoiceMailNumber(accountHandle, number);
+        } catch (Exception e) {
+            Log.e(this, e, "getSubscriptionIdForPhoneAccount");
+            throw e;
+        }
+    }
+
+    /**
      * @see android.telecom.TelecomManager#silenceRinger
      */
     @Override
diff --git a/src/com/android/server/telecom/TelephonyUtil.java b/src/com/android/server/telecom/TelephonyUtil.java
index 29b6f89..a130522 100644
--- a/src/com/android/server/telecom/TelephonyUtil.java
+++ b/src/com/android/server/telecom/TelephonyUtil.java
@@ -19,6 +19,8 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.net.Uri;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
 import android.telephony.PhoneNumberUtils;
 
 /**
@@ -33,8 +35,25 @@
     private static final String PSTN_CALL_SERVICE_CLASS_NAME =
             "com.android.services.telephony.TelephonyConnectionService";
 
+    private static final PhoneAccountHandle DEFAULT_EMERGENCY_PHONE_ACCOUNT_HANDLE =
+            new PhoneAccountHandle(
+                    new ComponentName(TELEPHONY_PACKAGE_NAME, PSTN_CALL_SERVICE_CLASS_NAME), "E");
+
     private TelephonyUtil() {}
 
+    /**
+     * @return fallback {@link PhoneAccount} to be used by Telecom for emergency calls in the
+     * rare case that Telephony has not registered any phone accounts yet. Details about this
+     * account are not expected to be displayed in the UI, so the description, etc are not
+     * populated.
+     */
+    static PhoneAccount getDefaultEmergencyPhoneAccount() {
+        return PhoneAccount.builder(DEFAULT_EMERGENCY_PHONE_ACCOUNT_HANDLE, "E")
+                .setCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
+                        PhoneAccount.CAPABILITY_CALL_PROVIDER |
+                        PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS).build();
+    }
+
     static boolean isPstnComponentName(ComponentName componentName) {
         final ComponentName pstnComponentName = new ComponentName(
                 TELEPHONY_PACKAGE_NAME, PSTN_CALL_SERVICE_CLASS_NAME);