am 4625edd0: am 9d29ded2: Merge "(Telecom-system part 2) Move telecom intialization from application to service." into lmp-mr1-dev

* commit '4625edd007e7f6270469e127698c6eb892024696':
  (Telecom-system part 2) Move telecom intialization from application to service.
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d0ae09c..4021d07 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -216,5 +216,12 @@
             </intent-filter>
         </service>
 
+        <service android:name=".TelecomService"
+                android:singleUser="true">
+            <intent-filter>
+                <android android:name="android.telecom.ITelecomService" />
+            </intent-filter>
+        </service>
+
     </application>
 </manifest>
diff --git a/src/com/android/server/telecom/TelecomApp.java b/src/com/android/server/telecom/TelecomApp.java
index f9df53c..8f46b49 100644
--- a/src/com/android/server/telecom/TelecomApp.java
+++ b/src/com/android/server/telecom/TelecomApp.java
@@ -17,19 +17,67 @@
 package com.android.server.telecom;
 
 import android.app.Application;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.ServiceManager;
 import android.os.UserHandle;
 
 /**
  * Top-level Application class for Telecom.
  */
 public final class TelecomApp extends Application {
+
+    /**
+     * Used to bind to the telecom service. Once created, the telecom service will start the telecom
+     * global state.
+     */
+    private class TelecomServiceConnection implements ServiceConnection {
+        /** {@inheritDoc} */
+        @Override public void onServiceConnected(ComponentName name, IBinder service) {
+            Log.i(this, "onServiceConnected: %s", name);
+            ServiceManager.addService(Context.TELECOM_SERVICE, service);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void onServiceDisconnected(ComponentName name) {
+            Log.i(this, "onDisconnected: %s", name);
+            bindToService();
+        }
+    }
+
+    private ServiceConnection mServiceConnection;
+
     /** {@inheritDoc} */
     @Override
     public void onCreate() {
         super.onCreate();
 
         if (UserHandle.myUserId() == UserHandle.USER_OWNER) {
-            TelecomGlobals.getInstance().initialize(this);
+            bindToService();
+        }
+    }
+
+    private void bindToService() {
+        if (mServiceConnection != null) {
+            unbindService(mServiceConnection);
+            mServiceConnection = null;
+        }
+
+        ComponentName componentName = new ComponentName(this, TelecomService.class);
+        Intent intent = new Intent(TelecomService.SERVICE_INTERFACE);
+        intent.setComponent(componentName);
+        int bindFlags = Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT;
+
+        Log.i(this, "binding to TelecomService.");
+        ServiceConnection serviceConnection = new TelecomServiceConnection();
+        if (bindServiceAsUser(intent, serviceConnection, bindFlags, UserHandle.OWNER)) {
+            mServiceConnection = serviceConnection;
+            Log.i(this, "TelecomService binding successful");
+        } else {
+            Log.e(this, null, "Failed to bind to TelecomService.");
         }
     }
 }
diff --git a/src/com/android/server/telecom/TelecomGlobals.java b/src/com/android/server/telecom/TelecomGlobals.java
index e30fee1..a11b470 100644
--- a/src/com/android/server/telecom/TelecomGlobals.java
+++ b/src/com/android/server/telecom/TelecomGlobals.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 
 /**
@@ -38,7 +37,7 @@
     /**
      * The Telecom service implementation.
      */
-    private TelecomServiceImpl mTelecomService;
+    private TelecomService mTelecomService;
 
     /**
      * Missed call notifier. Exists here so that the instance can be shared with
@@ -76,12 +75,12 @@
 
     void initialize(Context context) {
         if (mContext != null) {
-            Log.e(TAG, null, "Attempting to intialize TelecomGlobals a second time.");
+            Log.e(TAG, new Exception(), "Attempting to intialize TelecomGlobals a second time.");
             return;
         } else {
             Log.i(TAG, "TelecomGlobals initializing");
         }
-        mContext = context;
+        mContext = context.getApplicationContext();
 
         mMissedCallNotifier = new MissedCallNotifier(mContext);
         mPhoneAccountRegistrar = new PhoneAccountRegistrar(mContext);
@@ -89,10 +88,6 @@
         mCallsManager = new CallsManager(mContext, mMissedCallNotifier, mPhoneAccountRegistrar);
         CallsManager.initialize(mCallsManager);
 
-        mTelecomService = new TelecomServiceImpl(mMissedCallNotifier, mPhoneAccountRegistrar,
-                mCallsManager, mContext);
-        ServiceManager.addService(Context.TELECOM_SERVICE, mTelecomService);
-
         // Start the BluetoothPhoneService
         BluetoothPhoneService.start(mContext);
 
@@ -106,4 +101,8 @@
     PhoneAccountRegistrar getPhoneAccountRegistrar() {
         return mPhoneAccountRegistrar;
     }
+
+    CallsManager getCallsManager() {
+        return mCallsManager;
+    }
 }
diff --git a/src/com/android/server/telecom/TelecomService.java b/src/com/android/server/telecom/TelecomService.java
new file mode 100644
index 0000000..eab7947
--- /dev/null
+++ b/src/com/android/server/telecom/TelecomService.java
@@ -0,0 +1,956 @@
+/*
+ * 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.server.telecom;
+
+import android.Manifest;
+import android.annotation.SdkConstant;
+import android.app.AppOpsManager;
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.telecom.CallState;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+
+// TODO: Needed for move to system service: import com.android.internal.R;
+import com.android.internal.telecom.ITelecomService;
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implementation of the ITelecom interface.
+ */
+public class TelecomService extends Service {
+    /**
+     * The {@link Intent} that must be declared as handled by the service.
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE = "android.telecom.ITelecomService";
+
+    /** The context. */
+    private Context mContext;
+
+    /**
+     * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
+     * request after sending. The main thread will notify the request when it is complete.
+     */
+    private static final class MainThreadRequest {
+        /** The result of the request that is run on the main thread */
+        public Object result;
+        /** Object that can be used to store non-integer arguments */
+        public Object arg;
+    }
+
+    /**
+     * A handler that processes messages on the main thread. Since many of the method calls are not
+     * thread safe this is needed to shuttle the requests from the inbound binder threads to the
+     * main thread.
+     */
+    private final class MainThreadHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            if (msg.obj instanceof MainThreadRequest) {
+                MainThreadRequest request = (MainThreadRequest) msg.obj;
+                Object result = null;
+                switch (msg.what) {
+                    case MSG_SILENCE_RINGER:
+                        mCallsManager.getRinger().silence();
+                        break;
+                    case MSG_SHOW_CALL_SCREEN:
+                        mCallsManager.getInCallController().bringToForeground(msg.arg1 == 1);
+                        break;
+                    case MSG_END_CALL:
+                        result = endCallInternal();
+                        break;
+                    case MSG_ACCEPT_RINGING_CALL:
+                        acceptRingingCallInternal();
+                        break;
+                    case MSG_CANCEL_MISSED_CALLS_NOTIFICATION:
+                        mMissedCallNotifier.clearMissedCalls();
+                        break;
+                    case MSG_IS_TTY_SUPPORTED:
+                        result = mCallsManager.isTtySupported();
+                        break;
+                    case MSG_GET_CURRENT_TTY_MODE:
+                        result = mCallsManager.getCurrentTtyMode();
+                        break;
+                    case MSG_NEW_INCOMING_CALL:
+                        if (request.arg == null || !(request.arg instanceof Intent)) {
+                            Log.w(this, "Invalid new incoming call request");
+                            break;
+                        }
+                        CallReceiver.processIncomingCallIntent((Intent) request.arg);
+                        break;
+                }
+
+                if (result != null) {
+                    request.result = result;
+                    synchronized(request) {
+                        request.notifyAll();
+                    }
+                }
+            }
+        }
+    }
+
+    private static final String TAG = TelecomService.class.getSimpleName();
+
+    private static final String SERVICE_NAME = "telecom";
+
+    private static final int MSG_SILENCE_RINGER = 1;
+    private static final int MSG_SHOW_CALL_SCREEN = 2;
+    private static final int MSG_END_CALL = 3;
+    private static final int MSG_ACCEPT_RINGING_CALL = 4;
+    private static final int MSG_CANCEL_MISSED_CALLS_NOTIFICATION = 5;
+    private static final int MSG_IS_TTY_SUPPORTED = 6;
+    private static final int MSG_GET_CURRENT_TTY_MODE = 7;
+    private static final int MSG_NEW_INCOMING_CALL = 8;
+
+    private final MainThreadHandler mMainThreadHandler = new MainThreadHandler();
+
+    private CallsManager mCallsManager;
+    private MissedCallNotifier mMissedCallNotifier;
+    private PhoneAccountRegistrar mPhoneAccountRegistrar;
+    private AppOpsManager mAppOpsManager;
+    private UserManager mUserManager;
+    private PackageManager mPackageManager;
+    private TelecomServiceImpl mServiceImpl;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+
+        Log.d(this, "onCreate");
+        mContext = this;
+        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
+        mServiceImpl = new TelecomServiceImpl();
+
+        TelecomGlobals globals = TelecomGlobals.getInstance();
+        globals.initialize(this);
+
+        mMissedCallNotifier = globals.getMissedCallNotifier();
+        mPhoneAccountRegistrar = globals.getPhoneAccountRegistrar();
+        mCallsManager = globals.getCallsManager();
+        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        mPackageManager = mContext.getPackageManager();
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        Log.d(this, "onBind");
+        return mServiceImpl;
+    }
+
+    /**
+     * Implementation of the ITelecomService interface.
+     * TODO: Reorganize this inner class to top of file.
+     */
+    class TelecomServiceImpl extends ITelecomService.Stub {
+        @Override
+        public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme) {
+            try {
+                PhoneAccountHandle defaultOutgoingPhoneAccount =
+                        mPhoneAccountRegistrar.getDefaultOutgoingPhoneAccount(uriScheme);
+                // Make sure that the calling user can see this phone account.
+                if (defaultOutgoingPhoneAccount != null
+                        && !isVisibleToCaller(defaultOutgoingPhoneAccount)) {
+                    Log.w(this, "No account found for the calling user");
+                    return null;
+                }
+                return defaultOutgoingPhoneAccount;
+            } catch (Exception e) {
+                Log.e(this, e, "getDefaultOutgoingPhoneAccount");
+                throw e;
+            }
+        }
+
+        @Override
+        public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() {
+            try {
+                PhoneAccountHandle userSelectedOutgoingPhoneAccount =
+                        mPhoneAccountRegistrar.getUserSelectedOutgoingPhoneAccount();
+                // Make sure that the calling user can see this phone account.
+                if (!isVisibleToCaller(userSelectedOutgoingPhoneAccount)) {
+                    Log.w(this, "No account found for the calling user");
+                    return null;
+                }
+                return userSelectedOutgoingPhoneAccount;
+            } catch (Exception e) {
+                Log.e(this, e, "getUserSelectedOutgoingPhoneAccount");
+                throw e;
+            }
+        }
+
+        @Override
+        public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) {
+            enforceModifyPermission();
+
+            try {
+                mPhoneAccountRegistrar.setUserSelectedOutgoingPhoneAccount(accountHandle);
+            } catch (Exception e) {
+                Log.e(this, e, "setUserSelectedOutgoingPhoneAccount");
+                throw e;
+            }
+        }
+
+        @Override
+        public List<PhoneAccountHandle> getCallCapablePhoneAccounts() {
+            try {
+                return filterForAccountsVisibleToCaller(
+                        mPhoneAccountRegistrar.getCallCapablePhoneAccounts());
+            } catch (Exception e) {
+                Log.e(this, e, "getCallCapablePhoneAccounts");
+                throw e;
+            }
+        }
+
+        @Override
+        public List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(String uriScheme) {
+            try {
+                return filterForAccountsVisibleToCaller(
+                        mPhoneAccountRegistrar.getCallCapablePhoneAccounts(uriScheme));
+            } catch (Exception e) {
+                Log.e(this, e, "getPhoneAccountsSupportingScheme %s", uriScheme);
+                throw e;
+            }
+        }
+
+        @Override
+        public List<PhoneAccountHandle> getPhoneAccountsForPackage(String packageName) {
+            try {
+                return filterForAccountsVisibleToCaller(
+                        mPhoneAccountRegistrar.getPhoneAccountsForPackage(packageName));
+            } catch (Exception e) {
+                Log.e(this, e, "getPhoneAccountsForPackage %s", packageName);
+                throw e;
+            }
+        }
+
+        @Override
+        public PhoneAccount getPhoneAccount(PhoneAccountHandle accountHandle) {
+            try {
+                if (!isVisibleToCaller(accountHandle)) {
+                    Log.w(this, "%s is not visible for the calling user", accountHandle);
+                    return null;
+                }
+                return mPhoneAccountRegistrar.getPhoneAccountInternal(accountHandle);
+            } catch (Exception e) {
+                Log.e(this, e, "getPhoneAccount %s", accountHandle);
+                throw e;
+            }
+        }
+
+        @Override
+        public int getAllPhoneAccountsCount() {
+            try {
+                // This list is pre-filtered for the calling user.
+                return getAllPhoneAccounts().size();
+            } catch (Exception e) {
+                Log.e(this, e, "getAllPhoneAccountsCount");
+                throw e;
+            }
+        }
+
+        @Override
+        public List<PhoneAccount> getAllPhoneAccounts() {
+            try {
+                List<PhoneAccount> allPhoneAccounts = mPhoneAccountRegistrar.getAllPhoneAccounts();
+                List<PhoneAccount> profilePhoneAccounts = new ArrayList<>(allPhoneAccounts.size());
+                for (PhoneAccount phoneAccount : profilePhoneAccounts) {
+                    if (isVisibleToCaller(phoneAccount)) {
+                        profilePhoneAccounts.add(phoneAccount);
+                    }
+                }
+                return profilePhoneAccounts;
+            } catch (Exception e) {
+                Log.e(this, e, "getAllPhoneAccounts");
+                throw e;
+            }
+        }
+
+        @Override
+        public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
+            try {
+                return filterForAccountsVisibleToCaller(
+                        mPhoneAccountRegistrar.getAllPhoneAccountHandles());
+            } catch (Exception e) {
+                Log.e(this, e, "getAllPhoneAccounts");
+                throw e;
+            }
+        }
+
+        @Override
+        public PhoneAccountHandle getSimCallManager() {
+            try {
+                PhoneAccountHandle accountHandle = mPhoneAccountRegistrar.getSimCallManager();
+                if (!isVisibleToCaller(accountHandle)) {
+                    Log.w(this, "%s is not visible for the calling user", accountHandle);
+                    return null;
+                }
+                return accountHandle;
+            } catch (Exception e) {
+                Log.e(this, e, "getSimCallManager");
+                throw e;
+            }
+        }
+
+        @Override
+        public void setSimCallManager(PhoneAccountHandle accountHandle) {
+            enforceModifyPermission();
+
+            try {
+                mPhoneAccountRegistrar.setSimCallManager(accountHandle);
+            } catch (Exception e) {
+                Log.e(this, e, "setSimCallManager");
+                throw e;
+            }
+        }
+
+        @Override
+        public List<PhoneAccountHandle> getSimCallManagers() {
+            try {
+                return filterForAccountsVisibleToCaller(
+                        mPhoneAccountRegistrar.getConnectionManagerPhoneAccounts());
+            } catch (Exception e) {
+                Log.e(this, e, "getSimCallManagers");
+                throw e;
+            }
+        }
+
+        @Override
+        public void registerPhoneAccount(PhoneAccount account) {
+            try {
+                enforcePhoneAccountModificationForPackage(
+                        account.getAccountHandle().getComponentName().getPackageName());
+                if (account.hasCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)) {
+                    enforceRegisterCallProviderPermission();
+                }
+                if (account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
+                    enforceRegisterSimSubscriptionPermission();
+                }
+                if (account.hasCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)) {
+                    enforceRegisterConnectionManagerPermission();
+                }
+                if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) {
+                    enforceRegisterMultiUser();
+                }
+                enforceUserHandleMatchesCaller(account.getAccountHandle());
+
+                mPhoneAccountRegistrar.registerPhoneAccount(account);
+            } catch (Exception e) {
+                Log.e(this, e, "registerPhoneAccount %s", account);
+                throw e;
+            }
+        }
+
+        @Override
+        public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
+            try {
+                enforcePhoneAccountModificationForPackage(
+                        accountHandle.getComponentName().getPackageName());
+                enforceUserHandleMatchesCaller(accountHandle);
+                mPhoneAccountRegistrar.unregisterPhoneAccount(accountHandle);
+            } catch (Exception e) {
+                Log.e(this, e, "unregisterPhoneAccount %s", accountHandle);
+                throw e;
+            }
+        }
+
+        @Override
+        public void clearAccounts(String packageName) {
+            try {
+                enforcePhoneAccountModificationForPackage(packageName);
+                mPhoneAccountRegistrar.clearAccounts(packageName, Binder.getCallingUserHandle());
+            } catch (Exception e) {
+                Log.e(this, e, "clearAccounts %s", packageName);
+                throw e;
+            }
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#isVoiceMailNumber
+         */
+        @Override
+        public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number) {
+            enforceReadPermissionOrDefaultDialer();
+            try {
+                if (!isVisibleToCaller(accountHandle)) {
+                    Log.w(this, "%s is not visible for the calling user", accountHandle);
+                    return false;
+                }
+                return mPhoneAccountRegistrar.isVoiceMailNumber(accountHandle, number);
+            } catch (Exception e) {
+                Log.e(this, e, "getSubscriptionIdForPhoneAccount");
+                throw e;
+            }
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#hasVoiceMailNumber
+         */
+        @Override
+        public boolean hasVoiceMailNumber(PhoneAccountHandle accountHandle) {
+            enforceReadPermissionOrDefaultDialer();
+            try {
+                if (!isVisibleToCaller(accountHandle)) {
+                    Log.w(this, "%s is not visible for the calling user", accountHandle);
+                    return false;
+                }
+
+                int subId = SubscriptionManager.getDefaultVoiceSubId();
+                if (accountHandle != null) {
+                    subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle);
+                }
+                return !TextUtils.isEmpty(getTelephonyManager().getVoiceMailNumber(subId));
+            } catch (Exception e) {
+                Log.e(this, e, "getSubscriptionIdForPhoneAccount");
+                throw e;
+            }
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#silenceRinger
+         */
+        @Override
+        public void silenceRinger() {
+            Log.d(this, "silenceRinger");
+            enforceModifyPermission();
+            sendRequestAsync(MSG_SILENCE_RINGER, 0);
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#getDefaultPhoneApp
+         */
+        @Override
+        public ComponentName getDefaultPhoneApp() {
+            Resources resources = mContext.getResources();
+            return new ComponentName(
+                    resources.getString(R.string.ui_default_package),
+                    resources.getString(R.string.dialer_default_class));
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#isInCall
+         */
+        @Override
+        public boolean isInCall() {
+            enforceReadPermission();
+            // Do not use sendRequest() with this method since it could cause a deadlock with
+            // audio service, which we call into from the main thread: AudioManager.setMode().
+            final int callState = mCallsManager.getCallState();
+            return callState == TelephonyManager.CALL_STATE_OFFHOOK
+                    || callState == TelephonyManager.CALL_STATE_RINGING;
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#isRinging
+         */
+        @Override
+        public boolean isRinging() {
+            enforceReadPermission();
+            return mCallsManager.getCallState() == TelephonyManager.CALL_STATE_RINGING;
+        }
+
+        /**
+         * @see TelecomManager#getCallState
+         */
+        @Override
+        public int getCallState() {
+            return mCallsManager.getCallState();
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#endCall
+         */
+        @Override
+        public boolean endCall() {
+            enforceModifyPermission();
+            return (boolean) sendRequest(MSG_END_CALL);
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#acceptRingingCall
+         */
+        @Override
+        public void acceptRingingCall() {
+            enforceModifyPermission();
+            sendRequestAsync(MSG_ACCEPT_RINGING_CALL, 0);
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#showInCallScreen
+         */
+        @Override
+        public void showInCallScreen(boolean showDialpad) {
+            enforceReadPermissionOrDefaultDialer();
+            sendRequestAsync(MSG_SHOW_CALL_SCREEN, showDialpad ? 1 : 0);
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#cancelMissedCallsNotification
+         */
+        @Override
+        public void cancelMissedCallsNotification() {
+            enforceModifyPermissionOrDefaultDialer();
+            sendRequestAsync(MSG_CANCEL_MISSED_CALLS_NOTIFICATION, 0);
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#handleMmi
+         */
+        @Override
+        public boolean handlePinMmi(String dialString) {
+            enforceModifyPermissionOrDefaultDialer();
+
+            // Switch identity so that TelephonyManager checks Telecom's permissions instead.
+            long token = Binder.clearCallingIdentity();
+            boolean retval = false;
+            try {
+                retval = getTelephonyManager().handlePinMmi(dialString);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+
+            return retval;
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#handleMmi
+         */
+        @Override
+        public boolean handlePinMmiForPhoneAccount(PhoneAccountHandle accountHandle,
+                String dialString) {
+            enforceModifyPermissionOrDefaultDialer();
+
+            if (!isVisibleToCaller(accountHandle)) {
+                Log.w(this, "%s is not visible for the calling user", accountHandle);
+                return false;
+            }
+
+            // Switch identity so that TelephonyManager checks Telecom's permissions instead.
+            long token = Binder.clearCallingIdentity();
+            boolean retval = false;
+            try {
+                int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle);
+                retval = getTelephonyManager().handlePinMmiForSubscriber(subId, dialString);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+
+            return retval;
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#getAdnUriForPhoneAccount
+         */
+        @Override
+        public Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle) {
+            enforceModifyPermissionOrDefaultDialer();
+
+            if (!isVisibleToCaller(accountHandle)) {
+                Log.w(this, "%s is not visible for the calling user", accountHandle);
+                return null;
+            }
+
+            // Switch identity so that TelephonyManager checks Telecom's permissions instead.
+            long token = Binder.clearCallingIdentity();
+            String retval = "content://icc/adn/";
+            try {
+                long subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle);
+                retval = retval + "subId/" + subId;
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+
+            return Uri.parse(retval);
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#isTtySupported
+         */
+        @Override
+        public boolean isTtySupported() {
+            enforceReadPermission();
+            return (boolean) sendRequest(MSG_IS_TTY_SUPPORTED);
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#getCurrentTtyMode
+         */
+        @Override
+        public int getCurrentTtyMode() {
+            enforceReadPermission();
+            return (int) sendRequest(MSG_GET_CURRENT_TTY_MODE);
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#addNewIncomingCall
+         */
+        @Override
+        public void addNewIncomingCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
+            Log.i(this, "Adding new incoming call with phoneAccountHandle %s", phoneAccountHandle);
+            if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null) {
+                mAppOpsManager.checkPackage(
+                        Binder.getCallingUid(), phoneAccountHandle.getComponentName().getPackageName());
+
+                // Make sure it doesn't cross the UserHandle boundary
+                enforceUserHandleMatchesCaller(phoneAccountHandle);
+
+                Intent intent = new Intent(TelecomManager.ACTION_INCOMING_CALL);
+                intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
+                intent.putExtra(CallReceiver.KEY_IS_INCOMING_CALL, true);
+                if (extras != null) {
+                    intent.putExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, extras);
+                }
+                sendRequestAsync(MSG_NEW_INCOMING_CALL, 0, intent);
+            } else {
+                Log.w(this, "Null phoneAccountHandle. Ignoring request to add new incoming call");
+            }
+        }
+
+        /**
+         * @see android.telecom.TelecomManager#addNewUnknownCall
+         */
+        @Override
+        public void addNewUnknownCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
+            if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null &&
+                    TelephonyUtil.isPstnComponentName(phoneAccountHandle.getComponentName())) {
+                mAppOpsManager.checkPackage(
+                        Binder.getCallingUid(), phoneAccountHandle.getComponentName().getPackageName());
+
+                // Make sure it doesn't cross the UserHandle boundary
+                enforceUserHandleMatchesCaller(phoneAccountHandle);
+
+                Intent intent = new Intent(TelecomManager.ACTION_NEW_UNKNOWN_CALL);
+                intent.setClass(mContext, CallReceiver.class);
+                intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+                intent.putExtras(extras);
+                intent.putExtra(CallReceiver.KEY_IS_UNKNOWN_CALL, true);
+                intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
+                mContext.sendBroadcastAsUser(intent, phoneAccountHandle.getUserHandle());
+            } else {
+                Log.i(this, "Null phoneAccountHandle or not initiated by Telephony. Ignoring request"
+                        + " to add new unknown call.");
+            }
+        }
+    }
+
+    //
+    // Supporting methods for the ITelecomService interface implementation.
+    //
+
+    private boolean isVisibleToCaller(PhoneAccountHandle accountHandle) {
+        if (accountHandle == null) {
+            return false;
+        }
+
+        return isVisibleToCaller(mPhoneAccountRegistrar.getPhoneAccountInternal(accountHandle));
+    }
+
+    private boolean isVisibleToCaller(PhoneAccount account) {
+        if (account == null) {
+            return false;
+        }
+
+        // If this PhoneAccount has CAPABILITY_MULTI_USER, it should be visible to all users and
+        // all profiles. Only Telephony and SIP accounts should have this capability.
+        if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) {
+            return true;
+        }
+
+        UserHandle phoneAccountUserHandle = account.getAccountHandle().getUserHandle();
+        if (phoneAccountUserHandle == null) {
+            return false;
+        }
+
+        List<UserHandle> profileUserHandles;
+        if (isCallerSystemApp()) {
+            // If the caller lives in /system/priv-app, it can see PhoneAccounts for all of the
+            // *profiles* that the calling user owns, but not for any other *users*.
+            profileUserHandles = mUserManager.getUserProfiles();
+        } else {
+            // Otherwise, it has to be owned by the current caller's profile.
+            profileUserHandles = new ArrayList<>(1);
+            profileUserHandles.add(Binder.getCallingUserHandle());
+        }
+
+        return profileUserHandles.contains(phoneAccountUserHandle);
+    }
+
+    /**
+     * Given a list of {@link PhoneAccountHandle}s, filter them to the ones that the calling
+     * user can see.
+     *
+     * @param phoneAccountHandles Unfiltered list of account handles.
+     *
+     * @return {@link PhoneAccountHandle}s visible to the calling user and its profiles.
+     */
+    private List<PhoneAccountHandle> filterForAccountsVisibleToCaller(
+            List<PhoneAccountHandle> phoneAccountHandles) {
+        List<PhoneAccountHandle> profilePhoneAccountHandles =
+                new ArrayList<>(phoneAccountHandles.size());
+        for (PhoneAccountHandle phoneAccountHandle : phoneAccountHandles) {
+            if (isVisibleToCaller(phoneAccountHandle)) {
+                profilePhoneAccountHandles.add(phoneAccountHandle);
+            }
+        }
+        return profilePhoneAccountHandles;
+    }
+
+    private boolean isCallerSystemApp() {
+        int uid = Binder.getCallingUid();
+        String[] packages = mPackageManager.getPackagesForUid(uid);
+        for (String packageName : packages) {
+            if (isPackageSystemApp(packageName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isPackageSystemApp(String packageName) {
+        try {
+            ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(packageName,
+                    PackageManager.GET_META_DATA);
+            if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                return true;
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+        }
+        return false;
+    }
+
+    private void acceptRingingCallInternal() {
+        Call call = mCallsManager.getFirstCallWithState(CallState.RINGING);
+        if (call != null) {
+            call.answer(call.getVideoState());
+        }
+    }
+
+    private boolean endCallInternal() {
+        // Always operate on the foreground call if one exists, otherwise get the first call in
+        // priority order by call-state.
+        Call call = mCallsManager.getForegroundCall();
+        if (call == null) {
+            call = mCallsManager.getFirstCallWithState(
+                    CallState.ACTIVE,
+                    CallState.DIALING,
+                    CallState.RINGING,
+                    CallState.ON_HOLD);
+        }
+
+        if (call != null) {
+            if (call.getState() == CallState.RINGING) {
+                call.reject(false /* rejectWithMessage */, null);
+            } else {
+                call.disconnect();
+            }
+            return true;
+        }
+
+        return false;
+    }
+
+    private void enforcePhoneAccountModificationForPackage(String packageName) {
+        // TODO: Use a new telecomm permission for this instead of reusing modify.
+
+        int result = mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
+
+        // Callers with MODIFY_PHONE_STATE can use the PhoneAccount mechanism to implement
+        // built-in behavior even when PhoneAccounts are not exposed as a third-part API. They
+        // may also modify PhoneAccounts on behalf of any 'packageName'.
+
+        if (result != PackageManager.PERMISSION_GRANTED) {
+            // Other callers are only allowed to modify PhoneAccounts if the relevant system
+            // feature is enabled ...
+            enforceConnectionServiceFeature();
+            // ... and the PhoneAccounts they refer to are for their own package.
+            enforceCallingPackage(packageName);
+        }
+    }
+
+    private void enforceReadPermissionOrDefaultDialer() {
+        if (!isDefaultDialerCalling()) {
+            enforceReadPermission();
+        }
+    }
+
+    private void enforceModifyPermissionOrDefaultDialer() {
+        if (!isDefaultDialerCalling()) {
+            enforceModifyPermission();
+        }
+    }
+
+    private void enforceCallingPackage(String packageName) {
+        mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
+    }
+
+    private void enforceConnectionServiceFeature() {
+        enforceFeature(PackageManager.FEATURE_CONNECTION_SERVICE);
+    }
+
+    private void enforceRegisterCallProviderPermission() {
+        enforcePermission(android.Manifest.permission.REGISTER_CALL_PROVIDER);
+    }
+
+    private void enforceRegisterSimSubscriptionPermission() {
+        enforcePermission(android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION);
+    }
+
+    private void enforceRegisterConnectionManagerPermission() {
+        enforcePermission(android.Manifest.permission.REGISTER_CONNECTION_MANAGER);
+    }
+
+    private void enforceReadPermission() {
+        enforcePermission(Manifest.permission.READ_PHONE_STATE);
+    }
+
+    private void enforceModifyPermission() {
+        enforcePermission(Manifest.permission.MODIFY_PHONE_STATE);
+    }
+
+    private void enforcePermission(String permission) {
+        mContext.enforceCallingOrSelfPermission(permission, null);
+    }
+
+    private void enforceRegisterMultiUser() {
+        if (!isCallerSystemApp()) {
+            throw new SecurityException("CAPABILITY_MULTI_USER is only available to system apps.");
+        }
+    }
+
+    private void enforceUserHandleMatchesCaller(PhoneAccountHandle accountHandle) {
+        if (!Binder.getCallingUserHandle().equals(accountHandle.getUserHandle())) {
+            throw new SecurityException("Calling UserHandle does not match PhoneAccountHandle's");
+        }
+    }
+
+    private void enforceFeature(String feature) {
+        PackageManager pm = mContext.getPackageManager();
+        if (!pm.hasSystemFeature(feature)) {
+            throw new UnsupportedOperationException(
+                    "System does not support feature " + feature);
+        }
+    }
+
+    private boolean isDefaultDialerCalling() {
+        ComponentName defaultDialerComponent = getDefaultPhoneAppInternal();
+        if (defaultDialerComponent != null) {
+            try {
+                mAppOpsManager.checkPackage(
+                        Binder.getCallingUid(), defaultDialerComponent.getPackageName());
+                return true;
+            } catch (SecurityException e) {
+                Log.e(TAG, e, "Could not get default dialer.");
+            }
+        }
+        return false;
+    }
+
+    private ComponentName getDefaultPhoneAppInternal() {
+        Resources resources = mContext.getResources();
+        return new ComponentName(
+                resources.getString(R.string.ui_default_package),
+                resources.getString(R.string.dialer_default_class));
+    }
+
+    private TelephonyManager getTelephonyManager() {
+        return (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
+    }
+
+    private MainThreadRequest sendRequestAsync(int command, int arg1) {
+        return sendRequestAsync(command, arg1, null);
+    }
+
+    private MainThreadRequest sendRequestAsync(int command, int arg1, Object arg) {
+        MainThreadRequest request = new MainThreadRequest();
+        request.arg = arg;
+        mMainThreadHandler.obtainMessage(command, arg1, 0, request).sendToTarget();
+        return request;
+    }
+
+    /**
+     * Posts the specified command to be executed on the main thread, waits for the request to
+     * complete, and returns the result.
+     */
+    private Object sendRequest(int command) {
+        if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
+            MainThreadRequest request = new MainThreadRequest();
+            mMainThreadHandler.handleMessage(mMainThreadHandler.obtainMessage(command, request));
+            return request.result;
+        } else {
+            MainThreadRequest request = sendRequestAsync(command, 0);
+
+            // Wait for the request to complete
+            synchronized (request) {
+                while (request.result == null) {
+                    try {
+                        request.wait();
+                    } catch (InterruptedException e) {
+                        // Do nothing, go back and wait until the request is complete
+                    }
+                }
+            }
+            return request.result;
+        }
+    }
+
+    /**
+     * Dumps the current state of the TelecomService.  Used when generating problem reports.
+     *
+     * @param fd The file descriptor.
+     * @param writer The print writer to dump the state to.
+     * @param args Optional dump arguments.
+     */
+    @Override
+    protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+        final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
+        if (mCallsManager != null) {
+            pw.println("mCallsManager: ");
+            pw.increaseIndent();
+            mCallsManager.dump(pw);
+            pw.decreaseIndent();
+
+            pw.println("mPhoneAccountRegistrar: ");
+            pw.increaseIndent();
+            mPhoneAccountRegistrar.dump(pw);
+            pw.decreaseIndent();
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
deleted file mode 100644
index a7fbb6a..0000000
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ /dev/null
@@ -1,936 +0,0 @@
-/*
- * 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.server.telecom;
-
-import android.Manifest;
-import android.app.AppOpsManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.telecom.CallState;
-import android.telecom.PhoneAccount;
-import android.telecom.PhoneAccountHandle;
-import android.telecom.TelecomManager;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-
-
-// TODO: Needed for move to system service: import com.android.internal.R;
-import com.android.internal.telecom.ITelecomService;
-import com.android.internal.util.IndentingPrintWriter;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Implementation of the ITelecom interface.
- */
-public class TelecomServiceImpl extends ITelecomService.Stub {
-    /** The context. */
-    private Context mContext;
-
-    /** ${inheritDoc} */
-    @Override
-    public IBinder asBinder() {
-        return super.asBinder();
-    }
-
- /**
-     * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
-     * request after sending. The main thread will notify the request when it is complete.
-     */
-    private static final class MainThreadRequest {
-        /** The result of the request that is run on the main thread */
-        public Object result;
-        /** Object that can be used to store non-integer arguments */
-        public Object arg;
-    }
-
-    /**
-     * A handler that processes messages on the main thread in the phone process. Since many
-     * of the Phone calls are not thread safe this is needed to shuttle the requests from the
-     * inbound binder threads to the main thread in the phone process.
-     */
-    private final class MainThreadHandler extends Handler {
-        @Override
-        public void handleMessage(Message msg) {
-            if (msg.obj instanceof MainThreadRequest) {
-                MainThreadRequest request = (MainThreadRequest) msg.obj;
-                Object result = null;
-                switch (msg.what) {
-                    case MSG_SILENCE_RINGER:
-                        mCallsManager.getRinger().silence();
-                        break;
-                    case MSG_SHOW_CALL_SCREEN:
-                        mCallsManager.getInCallController().bringToForeground(msg.arg1 == 1);
-                        break;
-                    case MSG_END_CALL:
-                        result = endCallInternal();
-                        break;
-                    case MSG_ACCEPT_RINGING_CALL:
-                        acceptRingingCallInternal();
-                        break;
-                    case MSG_CANCEL_MISSED_CALLS_NOTIFICATION:
-                        mMissedCallNotifier.clearMissedCalls();
-                        break;
-                    case MSG_IS_TTY_SUPPORTED:
-                        result = mCallsManager.isTtySupported();
-                        break;
-                    case MSG_GET_CURRENT_TTY_MODE:
-                        result = mCallsManager.getCurrentTtyMode();
-                        break;
-                    case MSG_NEW_INCOMING_CALL:
-                        if (request.arg == null || !(request.arg instanceof Intent)) {
-                            Log.w(this, "Invalid new incoming call request");
-                            break;
-                        }
-                        CallReceiver.processIncomingCallIntent((Intent) request.arg);
-                        break;
-                }
-
-                if (result != null) {
-                    request.result = result;
-                    synchronized(request) {
-                        request.notifyAll();
-                    }
-                }
-            }
-        }
-    }
-
-    /** Private constructor; @see init() */
-    private static final String TAG = TelecomServiceImpl.class.getSimpleName();
-
-    private static final String SERVICE_NAME = "telecom";
-
-    private static final int MSG_SILENCE_RINGER = 1;
-    private static final int MSG_SHOW_CALL_SCREEN = 2;
-    private static final int MSG_END_CALL = 3;
-    private static final int MSG_ACCEPT_RINGING_CALL = 4;
-    private static final int MSG_CANCEL_MISSED_CALLS_NOTIFICATION = 5;
-    private static final int MSG_IS_TTY_SUPPORTED = 6;
-    private static final int MSG_GET_CURRENT_TTY_MODE = 7;
-    private static final int MSG_NEW_INCOMING_CALL = 8;
-
-    /** The singleton instance. */
-    private static TelecomServiceImpl sInstance;
-
-    private final MainThreadHandler mMainThreadHandler = new MainThreadHandler();
-    private final CallsManager mCallsManager;
-    private final MissedCallNotifier mMissedCallNotifier;
-    private final PhoneAccountRegistrar mPhoneAccountRegistrar;
-    private final AppOpsManager mAppOpsManager;
-    private final UserManager mUserManager;
-    private final PackageManager mPackageManager;
-
-    public TelecomServiceImpl(
-            MissedCallNotifier missedCallNotifier, PhoneAccountRegistrar phoneAccountRegistrar,
-            CallsManager callsManager, Context context) {
-        mMissedCallNotifier = missedCallNotifier;
-        mPhoneAccountRegistrar = phoneAccountRegistrar;
-        mCallsManager = callsManager;
-        mContext = context;
-        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
-        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        mPackageManager = mContext.getPackageManager();
-    }
-
-    //
-    // Implementation of the ITelecomService interface.
-    //
-
-    @Override
-    public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme) {
-        try {
-            PhoneAccountHandle defaultOutgoingPhoneAccount =
-                    mPhoneAccountRegistrar.getDefaultOutgoingPhoneAccount(uriScheme);
-            // Make sure that the calling user can see this phone account.
-            if (defaultOutgoingPhoneAccount != null
-                    && !isVisibleToCaller(defaultOutgoingPhoneAccount)) {
-                Log.w(this, "No account found for the calling user");
-                return null;
-            }
-            return defaultOutgoingPhoneAccount;
-        } catch (Exception e) {
-            Log.e(this, e, "getDefaultOutgoingPhoneAccount");
-            throw e;
-        }
-    }
-
-    @Override
-    public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() {
-        try {
-            PhoneAccountHandle userSelectedOutgoingPhoneAccount =
-                    mPhoneAccountRegistrar.getUserSelectedOutgoingPhoneAccount();
-            // Make sure that the calling user can see this phone account.
-            if (!isVisibleToCaller(userSelectedOutgoingPhoneAccount)) {
-                Log.w(this, "No account found for the calling user");
-                return null;
-            }
-            return userSelectedOutgoingPhoneAccount;
-        } catch (Exception e) {
-            Log.e(this, e, "getUserSelectedOutgoingPhoneAccount");
-            throw e;
-        }
-    }
-
-    @Override
-    public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) {
-        enforceModifyPermission();
-
-        try {
-            mPhoneAccountRegistrar.setUserSelectedOutgoingPhoneAccount(accountHandle);
-        } catch (Exception e) {
-            Log.e(this, e, "setUserSelectedOutgoingPhoneAccount");
-            throw e;
-        }
-    }
-
-    @Override
-    public List<PhoneAccountHandle> getCallCapablePhoneAccounts() {
-        try {
-            return filterForAccountsVisibleToCaller(
-                    mPhoneAccountRegistrar.getCallCapablePhoneAccounts());
-        } catch (Exception e) {
-            Log.e(this, e, "getCallCapablePhoneAccounts");
-            throw e;
-        }
-    }
-
-    @Override
-    public List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(String uriScheme) {
-        try {
-            return filterForAccountsVisibleToCaller(
-                    mPhoneAccountRegistrar.getCallCapablePhoneAccounts(uriScheme));
-        } catch (Exception e) {
-            Log.e(this, e, "getPhoneAccountsSupportingScheme %s", uriScheme);
-            throw e;
-        }
-    }
-
-    @Override
-    public List<PhoneAccountHandle> getPhoneAccountsForPackage(String packageName) {
-        try {
-            return filterForAccountsVisibleToCaller(
-                    mPhoneAccountRegistrar.getPhoneAccountsForPackage(packageName));
-        } catch (Exception e) {
-            Log.e(this, e, "getPhoneAccountsForPackage %s", packageName);
-            throw e;
-        }
-    }
-
-    @Override
-    public PhoneAccount getPhoneAccount(PhoneAccountHandle accountHandle) {
-        try {
-            if (!isVisibleToCaller(accountHandle)) {
-                Log.w(this, "%s is not visible for the calling user", accountHandle);
-                return null;
-            }
-            return mPhoneAccountRegistrar.getPhoneAccountInternal(accountHandle);
-        } catch (Exception e) {
-            Log.e(this, e, "getPhoneAccount %s", accountHandle);
-            throw e;
-        }
-    }
-
-    @Override
-    public int getAllPhoneAccountsCount() {
-        try {
-            // This list is pre-filtered for the calling user.
-            return getAllPhoneAccounts().size();
-        } catch (Exception e) {
-            Log.e(this, e, "getAllPhoneAccountsCount");
-            throw e;
-        }
-    }
-
-    @Override
-    public List<PhoneAccount> getAllPhoneAccounts() {
-        try {
-            List<PhoneAccount> allPhoneAccounts = mPhoneAccountRegistrar.getAllPhoneAccounts();
-            List<PhoneAccount> profilePhoneAccounts = new ArrayList<>(allPhoneAccounts.size());
-            for (PhoneAccount phoneAccount : profilePhoneAccounts) {
-                if (isVisibleToCaller(phoneAccount)) {
-                    profilePhoneAccounts.add(phoneAccount);
-                }
-            }
-            return profilePhoneAccounts;
-        } catch (Exception e) {
-            Log.e(this, e, "getAllPhoneAccounts");
-            throw e;
-        }
-    }
-
-    @Override
-    public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
-        try {
-            return filterForAccountsVisibleToCaller(
-                    mPhoneAccountRegistrar.getAllPhoneAccountHandles());
-        } catch (Exception e) {
-            Log.e(this, e, "getAllPhoneAccounts");
-            throw e;
-        }
-    }
-
-    @Override
-    public PhoneAccountHandle getSimCallManager() {
-        try {
-            PhoneAccountHandle accountHandle = mPhoneAccountRegistrar.getSimCallManager();
-            if (!isVisibleToCaller(accountHandle)) {
-                Log.w(this, "%s is not visible for the calling user", accountHandle);
-                return null;
-            }
-            return accountHandle;
-        } catch (Exception e) {
-            Log.e(this, e, "getSimCallManager");
-            throw e;
-        }
-    }
-
-    @Override
-    public void setSimCallManager(PhoneAccountHandle accountHandle) {
-        enforceModifyPermission();
-
-        try {
-            mPhoneAccountRegistrar.setSimCallManager(accountHandle);
-        } catch (Exception e) {
-            Log.e(this, e, "setSimCallManager");
-            throw e;
-        }
-    }
-
-    @Override
-    public List<PhoneAccountHandle> getSimCallManagers() {
-        try {
-            return filterForAccountsVisibleToCaller(
-                    mPhoneAccountRegistrar.getConnectionManagerPhoneAccounts());
-        } catch (Exception e) {
-            Log.e(this, e, "getSimCallManagers");
-            throw e;
-        }
-    }
-
-    @Override
-    public void registerPhoneAccount(PhoneAccount account) {
-        try {
-            enforcePhoneAccountModificationForPackage(
-                    account.getAccountHandle().getComponentName().getPackageName());
-            if (account.hasCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)) {
-                enforceRegisterCallProviderPermission();
-            }
-            if (account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
-                enforceRegisterSimSubscriptionPermission();
-            }
-            if (account.hasCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)) {
-                enforceRegisterConnectionManagerPermission();
-            }
-            if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) {
-                enforceRegisterMultiUser();
-            }
-            enforceUserHandleMatchesCaller(account.getAccountHandle());
-
-            mPhoneAccountRegistrar.registerPhoneAccount(account);
-        } catch (Exception e) {
-            Log.e(this, e, "registerPhoneAccount %s", account);
-            throw e;
-        }
-    }
-
-    @Override
-    public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
-        try {
-            enforcePhoneAccountModificationForPackage(
-                    accountHandle.getComponentName().getPackageName());
-            enforceUserHandleMatchesCaller(accountHandle);
-            mPhoneAccountRegistrar.unregisterPhoneAccount(accountHandle);
-        } catch (Exception e) {
-            Log.e(this, e, "unregisterPhoneAccount %s", accountHandle);
-            throw e;
-        }
-    }
-
-    @Override
-    public void clearAccounts(String packageName) {
-        try {
-            enforcePhoneAccountModificationForPackage(packageName);
-            mPhoneAccountRegistrar.clearAccounts(packageName, Binder.getCallingUserHandle());
-        } catch (Exception e) {
-            Log.e(this, e, "clearAccounts %s", packageName);
-            throw e;
-        }
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#isVoiceMailNumber
-     */
-    @Override
-    public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number) {
-        enforceReadPermissionOrDefaultDialer();
-        try {
-            if (!isVisibleToCaller(accountHandle)) {
-                Log.w(this, "%s is not visible for the calling user", accountHandle);
-                return false;
-            }
-            return mPhoneAccountRegistrar.isVoiceMailNumber(accountHandle, number);
-        } catch (Exception e) {
-            Log.e(this, e, "getSubscriptionIdForPhoneAccount");
-            throw e;
-        }
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#hasVoiceMailNumber
-     */
-    @Override
-    public boolean hasVoiceMailNumber(PhoneAccountHandle accountHandle) {
-        enforceReadPermissionOrDefaultDialer();
-        try {
-            if (!isVisibleToCaller(accountHandle)) {
-                Log.w(this, "%s is not visible for the calling user", accountHandle);
-                return false;
-            }
-
-            int subId = SubscriptionManager.getDefaultVoiceSubId();
-            if (accountHandle != null) {
-                subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle);
-            }
-            return !TextUtils.isEmpty(getTelephonyManager().getVoiceMailNumber(subId));
-        } catch (Exception e) {
-            Log.e(this, e, "getSubscriptionIdForPhoneAccount");
-            throw e;
-        }
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#silenceRinger
-     */
-    @Override
-    public void silenceRinger() {
-        Log.d(this, "silenceRinger");
-        enforceModifyPermission();
-        sendRequestAsync(MSG_SILENCE_RINGER, 0);
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#getDefaultPhoneApp
-     */
-    @Override
-    public ComponentName getDefaultPhoneApp() {
-        Resources resources = mContext.getResources();
-        return new ComponentName(
-                resources.getString(R.string.ui_default_package),
-                resources.getString(R.string.dialer_default_class));
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#isInCall
-     */
-    @Override
-    public boolean isInCall() {
-        enforceReadPermission();
-        // Do not use sendRequest() with this method since it could cause a deadlock with
-        // audio service, which we call into from the main thread: AudioManager.setMode().
-        final int callState = mCallsManager.getCallState();
-        return callState == TelephonyManager.CALL_STATE_OFFHOOK
-                || callState == TelephonyManager.CALL_STATE_RINGING;
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#isRinging
-     */
-    @Override
-    public boolean isRinging() {
-        enforceReadPermission();
-        return mCallsManager.getCallState() == TelephonyManager.CALL_STATE_RINGING;
-    }
-
-    /**
-     * @see TelecomManager#getCallState
-     */
-    @Override
-    public int getCallState() {
-        return mCallsManager.getCallState();
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#endCall
-     */
-    @Override
-    public boolean endCall() {
-        enforceModifyPermission();
-        return (boolean) sendRequest(MSG_END_CALL);
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#acceptRingingCall
-     */
-    @Override
-    public void acceptRingingCall() {
-        enforceModifyPermission();
-        sendRequestAsync(MSG_ACCEPT_RINGING_CALL, 0);
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#showInCallScreen
-     */
-    @Override
-    public void showInCallScreen(boolean showDialpad) {
-        enforceReadPermissionOrDefaultDialer();
-        sendRequestAsync(MSG_SHOW_CALL_SCREEN, showDialpad ? 1 : 0);
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#cancelMissedCallsNotification
-     */
-    @Override
-    public void cancelMissedCallsNotification() {
-        enforceModifyPermissionOrDefaultDialer();
-        sendRequestAsync(MSG_CANCEL_MISSED_CALLS_NOTIFICATION, 0);
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#handleMmi
-     */
-    @Override
-    public boolean handlePinMmi(String dialString) {
-        enforceModifyPermissionOrDefaultDialer();
-
-        // Switch identity so that TelephonyManager checks Telecom's permissions instead.
-        long token = Binder.clearCallingIdentity();
-        boolean retval = false;
-        try {
-            retval = getTelephonyManager().handlePinMmi(dialString);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-
-        return retval;
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#handleMmi
-     */
-    @Override
-    public boolean handlePinMmiForPhoneAccount(PhoneAccountHandle accountHandle,
-            String dialString) {
-        enforceModifyPermissionOrDefaultDialer();
-
-        if (!isVisibleToCaller(accountHandle)) {
-            Log.w(this, "%s is not visible for the calling user", accountHandle);
-            return false;
-        }
-
-        // Switch identity so that TelephonyManager checks Telecom's permissions instead.
-        long token = Binder.clearCallingIdentity();
-        boolean retval = false;
-        try {
-            int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle);
-            retval = getTelephonyManager().handlePinMmiForSubscriber(subId, dialString);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-
-        return retval;
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#getAdnUriForPhoneAccount
-     */
-    @Override
-    public Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle) {
-        enforceModifyPermissionOrDefaultDialer();
-
-        if (!isVisibleToCaller(accountHandle)) {
-            Log.w(this, "%s is not visible for the calling user", accountHandle);
-            return null;
-        }
-
-        // Switch identity so that TelephonyManager checks Telecom's permissions instead.
-        long token = Binder.clearCallingIdentity();
-        String retval = "content://icc/adn/";
-        try {
-            long subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle);
-            retval = retval + "subId/" + subId;
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-
-        return Uri.parse(retval);
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#isTtySupported
-     */
-    @Override
-    public boolean isTtySupported() {
-        enforceReadPermission();
-        return (boolean) sendRequest(MSG_IS_TTY_SUPPORTED);
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#getCurrentTtyMode
-     */
-    @Override
-    public int getCurrentTtyMode() {
-        enforceReadPermission();
-        return (int) sendRequest(MSG_GET_CURRENT_TTY_MODE);
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#addNewIncomingCall
-     */
-    @Override
-    public void addNewIncomingCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
-        Log.i(this, "Adding new incoming call with phoneAccountHandle %s", phoneAccountHandle);
-        if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null) {
-            mAppOpsManager.checkPackage(
-                    Binder.getCallingUid(), phoneAccountHandle.getComponentName().getPackageName());
-
-            // Make sure it doesn't cross the UserHandle boundary
-            enforceUserHandleMatchesCaller(phoneAccountHandle);
-
-            Intent intent = new Intent(TelecomManager.ACTION_INCOMING_CALL);
-            intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
-            intent.putExtra(CallReceiver.KEY_IS_INCOMING_CALL, true);
-            if (extras != null) {
-                intent.putExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, extras);
-            }
-            sendRequestAsync(MSG_NEW_INCOMING_CALL, 0, intent);
-        } else {
-            Log.w(this, "Null phoneAccountHandle. Ignoring request to add new incoming call");
-        }
-    }
-
-    /**
-     * @see android.telecom.TelecomManager#addNewUnknownCall
-     */
-    @Override
-    public void addNewUnknownCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
-        if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null &&
-                TelephonyUtil.isPstnComponentName(phoneAccountHandle.getComponentName())) {
-            mAppOpsManager.checkPackage(
-                    Binder.getCallingUid(), phoneAccountHandle.getComponentName().getPackageName());
-
-            // Make sure it doesn't cross the UserHandle boundary
-            enforceUserHandleMatchesCaller(phoneAccountHandle);
-
-            Intent intent = new Intent(TelecomManager.ACTION_NEW_UNKNOWN_CALL);
-            intent.setClass(mContext, CallReceiver.class);
-            intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-            intent.putExtras(extras);
-            intent.putExtra(CallReceiver.KEY_IS_UNKNOWN_CALL, true);
-            intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
-            mContext.sendBroadcastAsUser(intent, phoneAccountHandle.getUserHandle());
-        } else {
-            Log.i(this, "Null phoneAccountHandle or not initiated by Telephony. Ignoring request"
-                    + " to add new unknown call.");
-        }
-    }
-
-    //
-    // Supporting methods for the ITelecomService interface implementation.
-    //
-
-    private boolean isVisibleToCaller(PhoneAccountHandle accountHandle) {
-        if (accountHandle == null) {
-            return false;
-        }
-
-        return isVisibleToCaller(mPhoneAccountRegistrar.getPhoneAccountInternal(accountHandle));
-    }
-
-    private boolean isVisibleToCaller(PhoneAccount account) {
-        if (account == null) {
-            return false;
-        }
-
-        // If this PhoneAccount has CAPABILITY_MULTI_USER, it should be visible to all users and
-        // all profiles. Only Telephony and SIP accounts should have this capability.
-        if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) {
-            return true;
-        }
-
-        UserHandle phoneAccountUserHandle = account.getAccountHandle().getUserHandle();
-        if (phoneAccountUserHandle == null) {
-            return false;
-        }
-
-        List<UserHandle> profileUserHandles;
-        if (isCallerSystemApp()) {
-            // If the caller lives in /system/priv-app, it can see PhoneAccounts for all of the
-            // *profiles* that the calling user owns, but not for any other *users*.
-            profileUserHandles = mUserManager.getUserProfiles();
-        } else {
-            // Otherwise, it has to be owned by the current caller's profile.
-            profileUserHandles = new ArrayList<>(1);
-            profileUserHandles.add(Binder.getCallingUserHandle());
-        }
-
-        return profileUserHandles.contains(phoneAccountUserHandle);
-    }
-
-    /**
-     * Given a list of {@link PhoneAccountHandle}s, filter them to the ones that the calling
-     * user can see.
-     *
-     * @param phoneAccountHandles Unfiltered list of account handles.
-     *
-     * @return {@link PhoneAccountHandle}s visible to the calling user and its profiles.
-     */
-    private List<PhoneAccountHandle> filterForAccountsVisibleToCaller(
-            List<PhoneAccountHandle> phoneAccountHandles) {
-        List<PhoneAccountHandle> profilePhoneAccountHandles =
-                new ArrayList<>(phoneAccountHandles.size());
-        for (PhoneAccountHandle phoneAccountHandle : phoneAccountHandles) {
-            if (isVisibleToCaller(phoneAccountHandle)) {
-                profilePhoneAccountHandles.add(phoneAccountHandle);
-            }
-        }
-        return profilePhoneAccountHandles;
-    }
-
-    private boolean isCallerSystemApp() {
-        int uid = Binder.getCallingUid();
-        String[] packages = mPackageManager.getPackagesForUid(uid);
-        for (String packageName : packages) {
-            if (isPackageSystemApp(packageName)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean isPackageSystemApp(String packageName) {
-        try {
-            ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(packageName,
-                    PackageManager.GET_META_DATA);
-            if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
-                return true;
-            }
-        } catch (PackageManager.NameNotFoundException e) {
-        }
-        return false;
-    }
-
-    private void acceptRingingCallInternal() {
-        Call call = mCallsManager.getFirstCallWithState(CallState.RINGING);
-        if (call != null) {
-            call.answer(call.getVideoState());
-        }
-    }
-
-    private boolean endCallInternal() {
-        // Always operate on the foreground call if one exists, otherwise get the first call in
-        // priority order by call-state.
-        Call call = mCallsManager.getForegroundCall();
-        if (call == null) {
-            call = mCallsManager.getFirstCallWithState(
-                    CallState.ACTIVE,
-                    CallState.DIALING,
-                    CallState.RINGING,
-                    CallState.ON_HOLD);
-        }
-
-        if (call != null) {
-            if (call.getState() == CallState.RINGING) {
-                call.reject(false /* rejectWithMessage */, null);
-            } else {
-                call.disconnect();
-            }
-            return true;
-        }
-
-        return false;
-    }
-
-    private void enforcePhoneAccountModificationForPackage(String packageName) {
-        // TODO: Use a new telecomm permission for this instead of reusing modify.
-
-        int result = mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
-
-        // Callers with MODIFY_PHONE_STATE can use the PhoneAccount mechanism to implement
-        // built-in behavior even when PhoneAccounts are not exposed as a third-part API. They
-        // may also modify PhoneAccounts on behalf of any 'packageName'.
-
-        if (result != PackageManager.PERMISSION_GRANTED) {
-            // Other callers are only allowed to modify PhoneAccounts if the relevant system
-            // feature is enabled ...
-            enforceConnectionServiceFeature();
-            // ... and the PhoneAccounts they refer to are for their own package.
-            enforceCallingPackage(packageName);
-        }
-    }
-
-    private void enforceReadPermissionOrDefaultDialer() {
-        if (!isDefaultDialerCalling()) {
-            enforceReadPermission();
-        }
-    }
-
-    private void enforceModifyPermissionOrDefaultDialer() {
-        if (!isDefaultDialerCalling()) {
-            enforceModifyPermission();
-        }
-    }
-
-    private void enforceCallingPackage(String packageName) {
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
-    }
-
-    private void enforceConnectionServiceFeature() {
-        enforceFeature(PackageManager.FEATURE_CONNECTION_SERVICE);
-    }
-
-    private void enforceRegisterCallProviderPermission() {
-        enforcePermission(android.Manifest.permission.REGISTER_CALL_PROVIDER);
-    }
-
-    private void enforceRegisterSimSubscriptionPermission() {
-        enforcePermission(android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION);
-    }
-
-    private void enforceRegisterConnectionManagerPermission() {
-        enforcePermission(android.Manifest.permission.REGISTER_CONNECTION_MANAGER);
-    }
-
-    private void enforceReadPermission() {
-        enforcePermission(Manifest.permission.READ_PHONE_STATE);
-    }
-
-    private void enforceModifyPermission() {
-        enforcePermission(Manifest.permission.MODIFY_PHONE_STATE);
-    }
-
-    private void enforcePermission(String permission) {
-        mContext.enforceCallingOrSelfPermission(permission, null);
-    }
-
-    private void enforceRegisterMultiUser() {
-        if (!isCallerSystemApp()) {
-            throw new SecurityException("CAPABILITY_MULTI_USER is only available to system apps.");
-        }
-    }
-
-    private void enforceUserHandleMatchesCaller(PhoneAccountHandle accountHandle) {
-        if (!Binder.getCallingUserHandle().equals(accountHandle.getUserHandle())) {
-            throw new SecurityException("Calling UserHandle does not match PhoneAccountHandle's");
-        }
-    }
-
-    private void enforceFeature(String feature) {
-        PackageManager pm = mContext.getPackageManager();
-        if (!pm.hasSystemFeature(feature)) {
-            throw new UnsupportedOperationException(
-                    "System does not support feature " + feature);
-        }
-    }
-
-    private boolean isDefaultDialerCalling() {
-        ComponentName defaultDialerComponent = getDefaultPhoneApp();
-        if (defaultDialerComponent != null) {
-            try {
-                mAppOpsManager.checkPackage(
-                        Binder.getCallingUid(), defaultDialerComponent.getPackageName());
-                return true;
-            } catch (SecurityException e) {
-                Log.e(TAG, e, "Could not get default dialer.");
-            }
-        }
-        return false;
-    }
-
-    private TelephonyManager getTelephonyManager() {
-        return (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
-    }
-
-    private MainThreadRequest sendRequestAsync(int command, int arg1) {
-        return sendRequestAsync(command, arg1, null);
-    }
-
-    private MainThreadRequest sendRequestAsync(int command, int arg1, Object arg) {
-        MainThreadRequest request = new MainThreadRequest();
-        request.arg = arg;
-        mMainThreadHandler.obtainMessage(command, arg1, 0, request).sendToTarget();
-        return request;
-    }
-
-    /**
-     * Posts the specified command to be executed on the main thread, waits for the request to
-     * complete, and returns the result.
-     */
-    private Object sendRequest(int command) {
-        if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
-            MainThreadRequest request = new MainThreadRequest();
-            mMainThreadHandler.handleMessage(mMainThreadHandler.obtainMessage(command, request));
-            return request.result;
-        } else {
-            MainThreadRequest request = sendRequestAsync(command, 0);
-
-            // Wait for the request to complete
-            synchronized (request) {
-                while (request.result == null) {
-                    try {
-                        request.wait();
-                    } catch (InterruptedException e) {
-                        // Do nothing, go back and wait until the request is complete
-                    }
-                }
-            }
-            return request.result;
-        }
-    }
-
-    /**
-     * Dumps the current state of the TelecomService.  Used when generating problem reports.
-     *
-     * @param fd The file descriptor.
-     * @param writer The print writer to dump the state to.
-     * @param args Optional dump arguments.
-     */
-    @Override
-    protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
-        final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
-        if (mCallsManager != null) {
-            pw.println("mCallsManager: ");
-            pw.increaseIndent();
-            mCallsManager.dump(pw);
-            pw.decreaseIndent();
-
-            pw.println("mPhoneAccountRegistrar: ");
-            pw.increaseIndent();
-            mPhoneAccountRegistrar.dump(pw);
-            pw.decreaseIndent();
-        }
-    }
-}