diff --git a/src/com/android/services/telephony/EmergencyCallHelper.java b/src/com/android/services/telephony/EmergencyCallHelper.java
index c64a649..295f4f7 100644
--- a/src/com/android/services/telephony/EmergencyCallHelper.java
+++ b/src/com/android/services/telephony/EmergencyCallHelper.java
@@ -17,18 +17,17 @@
 package com.android.services.telephony;
 
 import android.content.Context;
-
 import android.content.Intent;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
 
-import com.android.internal.os.SomeArgs;
 import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.PhoneFactory;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
 
 /**
  * Helper class that implements special behavior related to emergency calls. Specifically, this
@@ -36,220 +35,75 @@
  * (i.e. the device is in airplane mode), by forcibly turning the radio back on, waiting for it to
  * come up, and then retrying the emergency call.
  */
-public class EmergencyCallHelper {
-
-    /**
-     * Receives the result of the EmergencyCallHelper's attempt to turn on the radio.
-     */
-    interface Callback {
-        void onComplete(boolean isRadioReady);
-    }
-
-    // Number of times to retry the call, and time between retry attempts.
-    public static final int MAX_NUM_RETRIES = 5;
-    public static final long TIME_BETWEEN_RETRIES_MILLIS = 5000;  // msec
-
-    // Handler message codes; see handleMessage()
-    private static final int MSG_START_SEQUENCE = 1;
-    private static final int MSG_SERVICE_STATE_CHANGED = 2;
-    private static final int MSG_RETRY_TIMEOUT = 3;
+public class EmergencyCallHelper implements EmergencyCallStateListener.Callback {
 
     private final Context mContext;
+    private EmergencyCallStateListener.Callback mCallback;
+    private List<EmergencyCallStateListener> mListeners;
+    private List<EmergencyCallStateListener> mInProgressListeners;
+    private boolean mIsEmergencyCallingEnabled;
 
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_START_SEQUENCE:
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    Phone phone = (Phone) args.arg1;
-                    EmergencyCallHelper.Callback callback =
-                            (EmergencyCallHelper.Callback) args.arg2;
-                    args.recycle();
-
-                    startSequenceInternal(phone, callback);
-                    break;
-                case MSG_SERVICE_STATE_CHANGED:
-                    onServiceStateChanged((ServiceState) ((AsyncResult) msg.obj).result);
-                    break;
-                case MSG_RETRY_TIMEOUT:
-                    onRetryTimeout();
-                    break;
-                default:
-                    Log.wtf(this, "handleMessage: unexpected message: %d.", msg.what);
-                    break;
-            }
-        }
-    };
-
-
-    private Callback mCallback;  // The callback to notify upon completion.
-    private Phone mPhone;  // The phone that will attempt to place the call.
-    private int mNumRetriesSoFar;
 
     public EmergencyCallHelper(Context context) {
-        Log.d(this, "EmergencyCallHelper constructor.");
         mContext = context;
+        mInProgressListeners = new ArrayList<>(2);
     }
 
+    private void setupListeners() {
+        if (mListeners != null) {
+            return;
+        }
+        mListeners = new ArrayList<>(2);
+        for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
+            mListeners.add(new EmergencyCallStateListener());
+        }
+    }
     /**
      * Starts the "turn on radio" sequence. This is the (single) external API of the
      * EmergencyCallHelper class.
      *
      * This method kicks off the following sequence:
-     * - Power on the radio.
+     * - Power on the radio for each Phone
      * - Listen for the service state change event telling us the radio has come up.
-     * - Retry if we've gone {@link #TIME_BETWEEN_RETRIES_MILLIS} without any response from the
-     *   radio.
+     * - Retry if we've gone a significant amount of time without any response from the radio.
      * - Finally, clean up any leftover state.
      *
      * This method is safe to call from any thread, since it simply posts a message to the
      * EmergencyCallHelper's handler (thus ensuring that the rest of the sequence is entirely
-     * serialized, and runs only on the handler thread.)
+     * serialized, and runs on the main looper.)
      */
-    public void startTurnOnRadioSequence(Phone phone, Callback callback) {
-        Log.d(this, "startTurnOnRadioSequence");
-
-        SomeArgs args = SomeArgs.obtain();
-        args.arg1 = phone;
-        args.arg2 = callback;
-        mHandler.obtainMessage(MSG_START_SEQUENCE, args).sendToTarget();
-    }
-
-    /**
-     * Actual implementation of startTurnOnRadioSequence(), guaranteed to run on the handler thread.
-     * @see #startTurnOnRadioSequence
-     */
-    private void startSequenceInternal(Phone phone, Callback callback) {
-        Log.d(this, "startSequenceInternal()");
-
-        // First of all, clean up any state left over from a prior emergency call sequence. This
-        // ensures that we'll behave sanely if another startTurnOnRadioSequence() comes in while
-        // we're already in the middle of the sequence.
-        cleanup();
-
-        mPhone = phone;
+    public void enableEmergencyCalling(EmergencyCallStateListener.Callback callback) {
+        setupListeners();
         mCallback = callback;
+        mInProgressListeners.clear();
+        mIsEmergencyCallingEnabled = false;
+        for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
+            Phone phone = PhoneFactory.getPhone(i);
+            if (phone == null)
+                continue;
 
-
-        // No need to check the current service state here, since the only reason to invoke this
-        // method in the first place is if the radio is powered-off. So just go ahead and turn the
-        // radio on.
-
-        powerOnRadio();  // We'll get an onServiceStateChanged() callback
-                         // when the radio successfully comes up.
-
-        // Next step: when the SERVICE_STATE_CHANGED event comes in, we'll retry the call; see
-        // onServiceStateChanged(). But also, just in case, start a timer to make sure we'll retry
-        // the call even if the SERVICE_STATE_CHANGED event never comes in for some reason.
-        startRetryTimer();
-    }
-
-    /**
-     * Handles the SERVICE_STATE_CHANGED event. Normally this event tells us that the radio has
-     * finally come up. In that case, it's now safe to actually place the emergency call.
-     */
-    private void onServiceStateChanged(ServiceState state) {
-        Log.d(this, "onServiceStateChanged(), new state = %s.", state);
-
-        // Possible service states:
-        // - STATE_IN_SERVICE        // Normal operation
-        // - STATE_OUT_OF_SERVICE    // Still searching for an operator to register to,
-        //                           // or no radio signal
-        // - STATE_EMERGENCY_ONLY    // Phone is locked; only emergency numbers are allowed
-        // - STATE_POWER_OFF         // Radio is explicitly powered off (airplane mode)
-
-        if (isOkToCall(state.getState(), mPhone.getState())) {
-            // Woo hoo!  It's OK to actually place the call.
-            Log.d(this, "onServiceStateChanged: ok to call!");
-
-            onComplete(true);
-            cleanup();
-        } else {
-            // The service state changed, but we're still not ready to call yet. (This probably was
-            // the transition from STATE_POWER_OFF to STATE_OUT_OF_SERVICE, which happens
-            // immediately after powering-on the radio.)
-            //
-            // So just keep waiting; we'll probably get to either STATE_IN_SERVICE or
-            // STATE_EMERGENCY_ONLY very shortly. (Or even if that doesn't happen, we'll at least do
-            // another retry when the RETRY_TIMEOUT event fires.)
-            Log.d(this, "onServiceStateChanged: not ready to call yet, keep waiting.");
+            mInProgressListeners.add(mListeners.get(i));
+            mListeners.get(i).waitForRadioOn(phone, this);
         }
+
+        powerOnRadio();
     }
-
-    private boolean isOkToCall(int serviceState, PhoneConstants.State phoneState) {
-        // Once we reach either STATE_IN_SERVICE or STATE_EMERGENCY_ONLY, it's finally OK to place
-        // the emergency call.
-        return ((phoneState == PhoneConstants.State.OFFHOOK)
-                || (serviceState == ServiceState.STATE_IN_SERVICE)
-                || (serviceState == ServiceState.STATE_EMERGENCY_ONLY)) ||
-
-                // Allow STATE_OUT_OF_SERVICE if we are at the max number of retries.
-                (mNumRetriesSoFar == MAX_NUM_RETRIES &&
-                 serviceState == ServiceState.STATE_OUT_OF_SERVICE);
-    }
-
     /**
-     * Handles the retry timer expiring.
-     */
-    private void onRetryTimeout() {
-        PhoneConstants.State phoneState = mPhone.getState();
-        int serviceState = mPhone.getServiceState().getState();
-        Log.d(this, "onRetryTimeout():  phone state = %s, service state = %d, retries = %d.",
-               phoneState, serviceState, mNumRetriesSoFar);
-
-        // - If we're actually in a call, we've succeeded.
-        // - Otherwise, if the radio is now on, that means we successfully got out of airplane mode
-        //   but somehow didn't get the service state change event.  In that case, try to place the
-        //   call.
-        // - If the radio is still powered off, try powering it on again.
-
-        if (isOkToCall(serviceState, phoneState)) {
-            Log.d(this, "onRetryTimeout: Radio is on. Cleaning up.");
-
-            // Woo hoo -- we successfully got out of airplane mode.
-            onComplete(true);
-            cleanup();
-        } else {
-            // Uh oh; we've waited the full TIME_BETWEEN_RETRIES_MILLIS and the radio is still not
-            // powered-on.  Try again.
-
-            mNumRetriesSoFar++;
-            Log.d(this, "mNumRetriesSoFar is now " + mNumRetriesSoFar);
-
-            if (mNumRetriesSoFar > MAX_NUM_RETRIES) {
-                Log.w(this, "Hit MAX_NUM_RETRIES; giving up.");
-                cleanup();
-            } else {
-                Log.d(this, "Trying (again) to turn on the radio.");
-                powerOnRadio();  // Again, we'll (hopefully) get an onServiceStateChanged() callback
-                                 // when the radio successfully comes up.
-                startRetryTimer();
-            }
-        }
-    }
-
-    /**
-     * Attempt to power on the radio (i.e. take the device out of airplane mode.)
-     * Additionally, start listening for service state changes; we'll eventually get an
-     * onServiceStateChanged() callback when the radio successfully comes up.
+     * Attempt to power on the radio (i.e. take the device out of airplane mode). We'll eventually
+     * get an onServiceStateChanged() callback when the radio successfully comes up.
      */
     private void powerOnRadio() {
         Log.d(this, "powerOnRadio().");
 
-        // We're about to turn on the radio, so arrange to be notified when the sequence is
-        // complete.
-        registerForServiceStateChanged();
-
         // If airplane mode is on, we turn it off the same way that the Settings activity turns it
         // off.
         if (Settings.Global.getInt(mContext.getContentResolver(),
-                                   Settings.Global.AIRPLANE_MODE_ON, 0) > 0) {
+                Settings.Global.AIRPLANE_MODE_ON, 0) > 0) {
             Log.d(this, "==> Turning off airplane mode.");
 
             // Change the system setting
             Settings.Global.putInt(mContext.getContentResolver(),
-                                   Settings.Global.AIRPLANE_MODE_ON, 0);
+                    Settings.Global.AIRPLANE_MODE_ON, 0);
 
             // Post the broadcast intend for change in airplane mode
             // TODO: We really should not be in charge of sending this broadcast.
@@ -258,77 +112,19 @@
             Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
             intent.putExtra("state", false);
             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
-        } else {
-            // Otherwise, for some strange reason the radio is off (even though the Settings
-            // database doesn't think we're in airplane mode.)  In this case just turn the radio
-            // back on.
-            Log.d(this, "==> (Apparently) not in airplane mode; manually powering radio on.");
-            mPhone.setRadioPower(true);
         }
     }
 
     /**
-     * Clean up when done with the whole sequence: either after successfully turning on the radio,
-     * or after bailing out because of too many failures.
-     *
-     * The exact cleanup steps are:
-     * - Notify callback if we still hadn't sent it a response.
-     * - Double-check that we're not still registered for any telephony events
-     * - Clean up any extraneous handler messages (like retry timeouts) still in the queue
-     *
-     * Basically this method guarantees that there will be no more activity from the
-     * EmergencyCallHelper until someone kicks off the whole sequence again with another call to
-     * {@link #startTurnOnRadioSequence}
-     *
-     * TODO: Do the work for the comment below:
-     * Note we don't call this method simply after a successful call to placeCall(), since it's
-     * still possible the call will disconnect very quickly with an OUT_OF_SERVICE error.
+     * This method is called from multiple Listeners on the Main Looper.
+     * Synchronization is not necessary.
      */
-    private void cleanup() {
-        Log.d(this, "cleanup()");
-
-        // This will send a failure call back if callback has yet to be invoked.  If the callback
-        // was already invoked, it's a no-op.
-        onComplete(false);
-
-        unregisterForServiceStateChanged();
-        cancelRetryTimer();
-
-        // Used for unregisterForServiceStateChanged() so we null it out here instead.
-        mPhone = null;
-        mNumRetriesSoFar = 0;
-    }
-
-    private void startRetryTimer() {
-        cancelRetryTimer();
-        mHandler.sendEmptyMessageDelayed(MSG_RETRY_TIMEOUT, TIME_BETWEEN_RETRIES_MILLIS);
-    }
-
-    private void cancelRetryTimer() {
-        mHandler.removeMessages(MSG_RETRY_TIMEOUT);
-    }
-
-    private void registerForServiceStateChanged() {
-        // Unregister first, just to make sure we never register ourselves twice.  (We need this
-        // because Phone.registerForServiceStateChanged() does not prevent multiple registration of
-        // the same handler.)
-        unregisterForServiceStateChanged();
-        mPhone.registerForServiceStateChanged(mHandler, MSG_SERVICE_STATE_CHANGED, null);
-    }
-
-    private void unregisterForServiceStateChanged() {
-        // This method is safe to call even if we haven't set mPhone yet.
-        if (mPhone != null) {
-            mPhone.unregisterForServiceStateChanged(mHandler);  // Safe even if unnecessary
-        }
-        mHandler.removeMessages(MSG_SERVICE_STATE_CHANGED);  // Clean up any pending messages too
-    }
-
-    private void onComplete(boolean isRadioReady) {
-        if (mCallback != null) {
-            Callback tempCallback = mCallback;
-            mCallback = null;
-            tempCallback.onComplete(isRadioReady);
+    @Override
+    public void onComplete(EmergencyCallStateListener listener, boolean isRadioReady) {
+        mIsEmergencyCallingEnabled |= isRadioReady;
+        mInProgressListeners.remove(listener);
+        if (mCallback != null && mInProgressListeners.isEmpty()) {
+            mCallback.onComplete(null, mIsEmergencyCallingEnabled);
         }
     }
 }
diff --git a/src/com/android/services/telephony/EmergencyCallStateListener.java b/src/com/android/services/telephony/EmergencyCallStateListener.java
new file mode 100644
index 0000000..19b3d36
--- /dev/null
+++ b/src/com/android/services/telephony/EmergencyCallStateListener.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2016 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.os.AsyncResult;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.telephony.ServiceState;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.SomeArgs;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+
+/**
+ * Helper class that listens to a Phone's radio state and sends a callback when the radio state of
+ * that Phone is either "in service" or "emergency calls only."
+ */
+public class EmergencyCallStateListener {
+
+    /**
+     * Receives the result of the EmergencyCallStateListener's attempt to turn on the radio.
+     */
+    interface Callback {
+        void onComplete(EmergencyCallStateListener listener, boolean isRadioReady);
+    }
+
+    // Number of times to retry the call, and time between retry attempts.
+    private static int MAX_NUM_RETRIES = 5;
+    private static long TIME_BETWEEN_RETRIES_MILLIS = 5000;  // msec
+
+    // Handler message codes; see handleMessage()
+    @VisibleForTesting
+    public static final int MSG_START_SEQUENCE = 1;
+    @VisibleForTesting
+    public static final int MSG_SERVICE_STATE_CHANGED = 2;
+    @VisibleForTesting
+    public static final int MSG_RETRY_TIMEOUT = 3;
+
+    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_START_SEQUENCE:
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        Phone phone = (Phone) args.arg1;
+                        EmergencyCallStateListener.Callback callback =
+                                (EmergencyCallStateListener.Callback) args.arg2;
+                        startSequenceInternal(phone, callback);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                case MSG_SERVICE_STATE_CHANGED:
+                    onServiceStateChanged((ServiceState) ((AsyncResult) msg.obj).result);
+                    break;
+                case MSG_RETRY_TIMEOUT:
+                    onRetryTimeout();
+                    break;
+                default:
+                    Log.wtf(this, "handleMessage: unexpected message: %d.", msg.what);
+                    break;
+            }
+        }
+    };
+
+
+    private Callback mCallback;  // The callback to notify upon completion.
+    private Phone mPhone;  // The phone that will attempt to place the call.
+    private int mNumRetriesSoFar;
+
+    /**
+     * Starts the "wait for radio" sequence. This is the (single) external API of the
+     * EmergencyCallStateListener class.
+     *
+     * This method kicks off the following sequence:
+     * - Listen for the service state change event telling us the radio has come up.
+     * - Retry if we've gone {@link #TIME_BETWEEN_RETRIES_MILLIS} without any response from the
+     *   radio.
+     * - Finally, clean up any leftover state.
+     *
+     * This method is safe to call from any thread, since it simply posts a message to the
+     * EmergencyCallStateListener's handler (thus ensuring that the rest of the sequence is entirely
+     * serialized, and runs only on the handler thread.)
+     */
+    public void waitForRadioOn(Phone phone, Callback callback) {
+        Log.d(this, "waitForRadioOn: Phone " + phone.getPhoneId());
+
+        if (mPhone != null) {
+            // If there already is an ongoing request, ignore the new one!
+            return;
+        }
+
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = phone;
+        args.arg2 = callback;
+        mHandler.obtainMessage(MSG_START_SEQUENCE, args).sendToTarget();
+    }
+
+    /**
+     * Actual implementation of waitForRadioOn(), guaranteed to run on the handler thread.
+     *
+     * @see #waitForRadioOn
+     */
+    private void startSequenceInternal(Phone phone, Callback callback) {
+        Log.d(this, "startSequenceInternal: Phone " + phone.getPhoneId());
+
+        // First of all, clean up any state left over from a prior emergency call sequence. This
+        // ensures that we'll behave sanely if another startTurnOnRadioSequence() comes in while
+        // we're already in the middle of the sequence.
+        cleanup();
+
+        mPhone = phone;
+        mCallback = callback;
+
+        registerForServiceStateChanged();
+        // Next step: when the SERVICE_STATE_CHANGED event comes in, we'll retry the call; see
+        // onServiceStateChanged(). But also, just in case, start a timer to make sure we'll retry
+        // the call even if the SERVICE_STATE_CHANGED event never comes in for some reason.
+        startRetryTimer();
+    }
+
+    /**
+     * Handles the SERVICE_STATE_CHANGED event. Normally this event tells us that the radio has
+     * finally come up. In that case, it's now safe to actually place the emergency call.
+     */
+    private void onServiceStateChanged(ServiceState state) {
+        Log.d(this, "onServiceStateChanged(), new state = %s, Phone ", state);
+
+        // Possible service states:
+        // - STATE_IN_SERVICE        // Normal operation
+        // - STATE_OUT_OF_SERVICE    // Still searching for an operator to register to,
+        //                           // or no radio signal
+        // - STATE_EMERGENCY_ONLY    // Phone is locked; only emergency numbers are allowed
+        // - STATE_POWER_OFF         // Radio is explicitly powered off (airplane mode)
+
+        if (isOkToCall(state.getState())) {
+            // Woo hoo!  It's OK to actually place the call.
+            Log.d(this, "onServiceStateChanged: ok to call!");
+
+            onComplete(true);
+            cleanup();
+        } else {
+            // The service state changed, but we're still not ready to call yet. (This probably was
+            // the transition from STATE_POWER_OFF to STATE_OUT_OF_SERVICE, which happens
+            // immediately after powering-on the radio.)
+            //
+            // So just keep waiting; we'll probably get to either STATE_IN_SERVICE or
+            // STATE_EMERGENCY_ONLY very shortly. (Or even if that doesn't happen, we'll at least do
+            // another retry when the RETRY_TIMEOUT event fires.)
+            Log.d(this, "onServiceStateChanged: not ready to call yet, keep waiting.");
+        }
+    }
+
+    private boolean isOkToCall(int serviceState) {
+        // Once we reach either STATE_IN_SERVICE or STATE_EMERGENCY_ONLY, it's finally OK to place
+        // the emergency call.
+        return ((mPhone.getState() == PhoneConstants.State.OFFHOOK)
+                || (serviceState == ServiceState.STATE_IN_SERVICE)
+                || (serviceState == ServiceState.STATE_EMERGENCY_ONLY))
+                // STATE_EMERGENCY_ONLY currently is not used, so we must also check the service
+                // state for emergency only calling.
+                || (serviceState == ServiceState.STATE_OUT_OF_SERVICE &&
+                        mPhone.getServiceState().isEmergencyOnly())
+                // Allow STATE_OUT_OF_SERVICE if we are at the max number of retries.
+                || (mNumRetriesSoFar == MAX_NUM_RETRIES &&
+                        serviceState == ServiceState.STATE_OUT_OF_SERVICE);
+    }
+
+    /**
+     * Handles the retry timer expiring.
+     */
+    private void onRetryTimeout() {
+        int serviceState = mPhone.getServiceState().getState();
+        Log.d(this, "onRetryTimeout():  phone state = %s, service state = %d, retries = %d.",
+                mPhone.getState(), serviceState, mNumRetriesSoFar);
+
+        // - If we're actually in a call, we've succeeded.
+        // - Otherwise, if the radio is now on, that means we successfully got out of airplane mode
+        //   but somehow didn't get the service state change event.  In that case, try to place the
+        //   call.
+        // - If the radio is still powered off, try powering it on again.
+
+        if (isOkToCall(serviceState)) {
+            Log.d(this, "onRetryTimeout: Radio is on. Cleaning up.");
+
+            // Woo hoo -- we successfully got out of airplane mode.
+            onComplete(true);
+            cleanup();
+        } else {
+            // Uh oh; we've waited the full TIME_BETWEEN_RETRIES_MILLIS and the radio is still not
+            // powered-on.  Try again.
+
+            mNumRetriesSoFar++;
+            Log.d(this, "mNumRetriesSoFar is now " + mNumRetriesSoFar);
+
+            if (mNumRetriesSoFar > MAX_NUM_RETRIES) {
+                Log.w(this, "Hit MAX_NUM_RETRIES; giving up.");
+                cleanup();
+            } else {
+                Log.d(this, "Trying (again) to turn on the radio.");
+                mPhone.setRadioPower(true);
+                startRetryTimer();
+            }
+        }
+    }
+
+    /**
+     * Clean up when done with the whole sequence: either after successfully turning on the radio,
+     * or after bailing out because of too many failures.
+     *
+     * The exact cleanup steps are:
+     * - Notify callback if we still hadn't sent it a response.
+     * - Double-check that we're not still registered for any telephony events
+     * - Clean up any extraneous handler messages (like retry timeouts) still in the queue
+     *
+     * Basically this method guarantees that there will be no more activity from the
+     * EmergencyCallStateListener until someone kicks off the whole sequence again with another call
+     * to {@link #waitForRadioOn}
+     *
+     * TODO: Do the work for the comment below:
+     * Note we don't call this method simply after a successful call to placeCall(), since it's
+     * still possible the call will disconnect very quickly with an OUT_OF_SERVICE error.
+     */
+    private void cleanup() {
+        Log.d(this, "cleanup()");
+
+        // This will send a failure call back if callback has yet to be invoked.  If the callback
+        // was already invoked, it's a no-op.
+        onComplete(false);
+
+        unregisterForServiceStateChanged();
+        cancelRetryTimer();
+
+        // Used for unregisterForServiceStateChanged() so we null it out here instead.
+        mPhone = null;
+        mNumRetriesSoFar = 0;
+    }
+
+    private void startRetryTimer() {
+        cancelRetryTimer();
+        mHandler.sendEmptyMessageDelayed(MSG_RETRY_TIMEOUT, TIME_BETWEEN_RETRIES_MILLIS);
+    }
+
+    private void cancelRetryTimer() {
+        mHandler.removeMessages(MSG_RETRY_TIMEOUT);
+    }
+
+    private void registerForServiceStateChanged() {
+        // Unregister first, just to make sure we never register ourselves twice.  (We need this
+        // because Phone.registerForServiceStateChanged() does not prevent multiple registration of
+        // the same handler.)
+        unregisterForServiceStateChanged();
+        mPhone.registerForServiceStateChanged(mHandler, MSG_SERVICE_STATE_CHANGED, null);
+    }
+
+    private void unregisterForServiceStateChanged() {
+        // This method is safe to call even if we haven't set mPhone yet.
+        if (mPhone != null) {
+            mPhone.unregisterForServiceStateChanged(mHandler);  // Safe even if unnecessary
+        }
+        mHandler.removeMessages(MSG_SERVICE_STATE_CHANGED);  // Clean up any pending messages too
+    }
+
+    private void onComplete(boolean isRadioReady) {
+        if (mCallback != null) {
+            Callback tempCallback = mCallback;
+            mCallback = null;
+            tempCallback.onComplete(this, isRadioReady);
+        }
+    }
+
+    @VisibleForTesting
+    public Handler getHandler() {
+        return mHandler;
+    }
+
+    @VisibleForTesting
+    public void setMaxNumRetries(int retries) {
+        MAX_NUM_RETRIES = retries;
+    }
+
+    @VisibleForTesting
+    public void setTimeBetweenRetriesMillis(long timeMs) {
+        TIME_BETWEEN_RETRIES_MILLIS = timeMs;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || !getClass().equals(o.getClass())) return false;
+
+        EmergencyCallStateListener that = (EmergencyCallStateListener) o;
+
+        if (mNumRetriesSoFar != that.mNumRetriesSoFar) {
+            return false;
+        }
+        if (mCallback != null ? !mCallback.equals(that.mCallback) : that.mCallback != null) {
+            return false;
+        }
+        return mPhone != null ? mPhone.equals(that.mPhone) : that.mPhone == null;
+
+    }
+}
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index a4434dd..0846c59 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -311,10 +311,10 @@
             if (mEmergencyCallHelper == null) {
                 mEmergencyCallHelper = new EmergencyCallHelper(this);
             }
-            mEmergencyCallHelper.startTurnOnRadioSequence(phone,
-                    new EmergencyCallHelper.Callback() {
+            mEmergencyCallHelper.enableEmergencyCalling(new EmergencyCallStateListener.Callback() {
                         @Override
-                        public void onComplete(boolean isRadioReady) {
+                        public void onComplete(EmergencyCallStateListener listener,
+                                boolean isRadioReady) {
                             if (connection.getState() == Connection.STATE_DISCONNECTED) {
                                 // If the connection has already been disconnected, do nothing.
                             } else if (isRadioReady) {
diff --git a/tests/Android.mk b/tests/Android.mk
index 6cc0355..e1b564f 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -25,6 +25,8 @@
 
 LOCAL_MODULE_TAGS := tests
 
+LOCAL_JAVA_LIBRARIES := telephony-common
+
 LOCAL_INSTRUMENTATION_FOR := TeleService
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 8900568..cae4c1b 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -62,17 +62,16 @@
     </application>
 
     <!--
-        The prefered way is to use 'runtest':
-           runtest phone-unit
+        To run all tests:
+            adb shell am instrument -w
+                com.android.phone.tests/android.support.test.runner.AndroidJUnitRunner
 
-         runtest is a wrapper around 'adb shell'. The low level shell command is:
-           adb shell am instrument -w com.android.phone.tests/android.test.InstrumentationTestRunner
+        To run a single class test:
+            adb shell am instrument -e class com.android.phone.unit.FooUnitTest
+                -w com.android.phone.tests/android.support.test.runner.AndroidJUnitRunner
 
-         To run a single test case:
-           adb shell am instrument -w com.android.phone.tests/android.test.InstrumentationTestRunner
-                                   -e com.android.phone.unit.FooUnitTest
     -->
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
         android:targetPackage="com.android.phone"
         android:label="Phone application tests." />
 </manifest>
diff --git a/tests/src/com/android/TelephonyTestBase.java b/tests/src/com/android/TelephonyTestBase.java
new file mode 100644
index 0000000..6dee12b
--- /dev/null
+++ b/tests/src/com/android/TelephonyTestBase.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 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;
+
+import android.content.Context;
+import android.os.Handler;
+import android.support.test.InstrumentationRegistry;
+
+import com.android.phone.MockitoHelper;
+
+import org.mockito.MockitoAnnotations;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Helper class to load Mockito Resources into a test.
+ */
+public class TelephonyTestBase {
+
+    protected Context mContext;
+    MockitoHelper mMockitoHelper = new MockitoHelper();
+
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mMockitoHelper.setUp(mContext, getClass());
+        MockitoAnnotations.initMocks(this);
+    }
+
+    public void tearDown() throws Exception {
+        mMockitoHelper.tearDown();
+    }
+
+    protected final void waitForHandlerAction(Handler h, long timeoutMillis) {
+        final CountDownLatch lock = new CountDownLatch(1);
+        h.post(lock::countDown);
+        while (lock.getCount() > 0) {
+            try {
+                lock.await(timeoutMillis, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                // do nothing
+            }
+        }
+    }
+
+    protected final void waitForHandlerActionDelayed(Handler h, long timeoutMillis, long delayMs) {
+        final CountDownLatch lock = new CountDownLatch(1);
+        h.postDelayed(lock::countDown, delayMs);
+        while (lock.getCount() > 0) {
+            try {
+                lock.await(timeoutMillis, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                // do nothing
+            }
+        }
+    }
+}
diff --git a/tests/src/com/android/phone/MockitoHelper.java b/tests/src/com/android/phone/MockitoHelper.java
index 3da5d6e..7998030 100644
--- a/tests/src/com/android/phone/MockitoHelper.java
+++ b/tests/src/com/android/phone/MockitoHelper.java
@@ -16,6 +16,8 @@
 
 package com.android.phone;
 
+import android.content.Context;
+
 import com.android.services.telephony.Log;
 
 /**
@@ -24,6 +26,7 @@
 public final class MockitoHelper {
 
     private static final String TAG = "MockitoHelper";
+    private static final String DEXCACHE = "dexmaker.dexcache";
 
     private ClassLoader mOriginalClassLoader;
     private Thread mContextThread;
@@ -34,7 +37,7 @@
      *
      * @param packageClass test case class
      */
-    public void setUp(Class<?> packageClass) throws Exception {
+    public void setUp(Context context, Class<?> packageClass) throws Exception {
         // makes a copy of the context classloader
         mContextThread = Thread.currentThread();
         mOriginalClassLoader = mContextThread.getContextClassLoader();
@@ -42,6 +45,9 @@
         Log.v(TAG, "Changing context classloader from " + mOriginalClassLoader
                 + " to " + newClassLoader);
         mContextThread.setContextClassLoader(newClassLoader);
+        String dexCache = context.getCacheDir().toString();
+        Log.v(this, "Setting property %s to %s", DEXCACHE, dexCache);
+        System.setProperty(DEXCACHE, dexCache);
     }
 
     /**
@@ -50,5 +56,6 @@
     public void tearDown() throws Exception {
         Log.v(TAG, "Restoring context classloader to " + mOriginalClassLoader);
         mContextThread.setContextClassLoader(mOriginalClassLoader);
+        System.clearProperty(DEXCACHE);
     }
 }
\ No newline at end of file
diff --git a/tests/src/com/android/phone/common/mail/MailTransportTest.java b/tests/src/com/android/phone/common/mail/MailTransportTest.java
index 6acd517..9eaef6b 100644
--- a/tests/src/com/android/phone/common/mail/MailTransportTest.java
+++ b/tests/src/com/android/phone/common/mail/MailTransportTest.java
@@ -61,7 +61,7 @@
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        mMokitoHelper.setUp(getClass());
+        mMokitoHelper.setUp(getContext(), getClass());
         MockitoAnnotations.initMocks(this);
     }
 
diff --git a/tests/src/com/android/services/telephony/EmergencyCallStateListenerTest.java b/tests/src/com/android/services/telephony/EmergencyCallStateListenerTest.java
new file mode 100644
index 0000000..64cf052
--- /dev/null
+++ b/tests/src/com/android/services/telephony/EmergencyCallStateListenerTest.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2016 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.os.AsyncResult;
+import android.os.Handler;
+import android.telephony.ServiceState;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.TelephonyTestBase;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.when;
+
+/**
+ * Tests the EmergencyCallStateListener, which listens to one Phone and waits until its service
+ * state changes to accepting emergency calls or in service. If it can not find a tower to camp onto
+ * for emergency calls, then it will fail after a timeout period.
+ */
+@RunWith(AndroidJUnit4.class)
+public class EmergencyCallStateListenerTest extends TelephonyTestBase {
+
+    private static final long TIMEOUT_MS = 100;
+
+    @Mock Phone mMockPhone;
+    @Mock EmergencyCallStateListener.Callback mCallback;
+    EmergencyCallStateListener mListener;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        mListener = new EmergencyCallStateListener();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mListener.getHandler().removeCallbacksAndMessages(null);
+        super.tearDown();
+    }
+
+    @Test
+    public void testRegisterForCallback() {
+        mListener.waitForRadioOn(mMockPhone, mCallback);
+
+        waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
+
+        verify(mMockPhone).unregisterForServiceStateChanged(any(Handler.class));
+        verify(mMockPhone).registerForServiceStateChanged(any(Handler.class),
+                eq(EmergencyCallStateListener.MSG_SERVICE_STATE_CHANGED), isNull());
+    }
+
+    @Test
+    public void testPhoneChangeState_InService() {
+        ServiceState state = new ServiceState();
+        state.setState(ServiceState.STATE_IN_SERVICE);
+        when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
+        mListener.waitForRadioOn(mMockPhone, mCallback);
+        waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
+
+        mListener.getHandler().obtainMessage(EmergencyCallStateListener.MSG_SERVICE_STATE_CHANGED,
+                new AsyncResult(null, state, null)).sendToTarget();
+
+        waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
+        verify(mCallback).onComplete(eq(mListener), eq(true));
+    }
+
+    @Test
+    public void testPhoneChangeState_EmergencyCalls() {
+        ServiceState state = new ServiceState();
+        state.setState(ServiceState.STATE_OUT_OF_SERVICE);
+        state.setEmergencyOnly(true);
+        when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
+        when(mMockPhone.getServiceState()).thenReturn(state);
+        mListener.waitForRadioOn(mMockPhone, mCallback);
+        waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
+
+        mListener.getHandler().obtainMessage(EmergencyCallStateListener.MSG_SERVICE_STATE_CHANGED,
+                new AsyncResult(null, state, null)).sendToTarget();
+
+        waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
+        verify(mCallback).onComplete(eq(mListener), eq(true));
+    }
+
+    @Test
+    public void testPhoneChangeState_OutOfService() {
+        ServiceState state = new ServiceState();
+        state.setState(ServiceState.STATE_OUT_OF_SERVICE);
+        when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
+        when(mMockPhone.getServiceState()).thenReturn(state);
+        mListener.waitForRadioOn(mMockPhone, mCallback);
+        waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
+
+        // Don't expect any answer, since it is not the one that we want and the timeout for giving
+        // up hasn't expired yet.
+        mListener.getHandler().obtainMessage(EmergencyCallStateListener.MSG_SERVICE_STATE_CHANGED,
+                new AsyncResult(null, state, null)).sendToTarget();
+
+        waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
+        verify(mCallback, never()).onComplete(any(EmergencyCallStateListener.class), anyBoolean());
+    }
+
+    @Test
+    public void testTimeout_EmergencyCalls() {
+        ServiceState state = new ServiceState();
+        state.setState(ServiceState.STATE_OUT_OF_SERVICE);
+        state.setEmergencyOnly(true);
+        when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
+        when(mMockPhone.getServiceState()).thenReturn(state);
+        mListener.waitForRadioOn(mMockPhone, mCallback);
+        mListener.setTimeBetweenRetriesMillis(500);
+
+        // Wait for the timer to expire and check state manually in onRetryTimeout
+        waitForHandlerActionDelayed(mListener.getHandler(), TIMEOUT_MS, 600);
+
+        verify(mCallback).onComplete(eq(mListener), eq(true));
+    }
+
+    @Test
+    public void testTimeout_RetryFailure() {
+        ServiceState state = new ServiceState();
+        state.setState(ServiceState.STATE_POWER_OFF);
+        when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
+        when(mMockPhone.getServiceState()).thenReturn(state);
+        mListener.waitForRadioOn(mMockPhone, mCallback);
+        mListener.setTimeBetweenRetriesMillis(100);
+        mListener.setMaxNumRetries(2);
+
+        // Wait for the timer to expire and check state manually in onRetryTimeout
+        waitForHandlerActionDelayed(mListener.getHandler(), TIMEOUT_MS, 600);
+
+        verify(mCallback).onComplete(eq(mListener), eq(false));
+        verify(mMockPhone, times(2)).setRadioPower(eq(true));
+    }
+
+}
