16556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon/*
26556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon * Copyright (C) 2014 The Android Open Source Project
36556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon *
46556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License");
56556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon * you may not use this file except in compliance with the License.
66556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon * You may obtain a copy of the License at
76556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon *
86556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon *      http://www.apache.org/licenses/LICENSE-2.0
96556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon *
106556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon * Unless required by applicable law or agreed to in writing, software
116556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS,
126556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon * See the License for the specific language governing permissions and
146556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon * limitations under the License.
156556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon */
166556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
176556a09daab949853c384b385bc7618a6c75d9ddSantos Cordonpackage com.android.services.telephony.sip;
186556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
196556a09daab949853c384b385bc7618a6c75d9ddSantos Cordonimport android.content.Context;
206556a09daab949853c384b385bc7618a6c75d9ddSantos Cordonimport android.net.sip.SipException;
216556a09daab949853c384b385bc7618a6c75d9ddSantos Cordonimport android.net.sip.SipManager;
226556a09daab949853c384b385bc7618a6c75d9ddSantos Cordonimport android.net.sip.SipProfile;
234d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.PhoneAccount;
244d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.PhoneAccountHandle;
254d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.TelecomManager;
266556a09daab949853c384b385bc7618a6c75d9ddSantos Cordonimport android.util.Log;
276556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
286556a09daab949853c384b385bc7618a6c75d9ddSantos Cordonimport java.util.List;
296556a09daab949853c384b385bc7618a6c75d9ddSantos Cordonimport java.util.Objects;
306556a09daab949853c384b385bc7618a6c75d9ddSantos Cordonimport java.util.concurrent.CopyOnWriteArrayList;
316556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
326556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon/**
336556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon * Manages the {@link PhoneAccount} entries for SIP calling.
346556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon */
354d37f5279f2896d16ec3d4e10ec4dcba63e86c3cAndrew Leepublic final class SipAccountRegistry {
366556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    private final class AccountEntry {
376556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon        private final SipProfile mProfile;
386556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
396556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon        AccountEntry(SipProfile profile) {
406556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon            mProfile = profile;
416556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon        }
426556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
436556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon        SipProfile getProfile() {
446556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon            return mProfile;
456556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon        }
466556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
47baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        /**
48baee2955f596f7b79971feb12fa21031a069677dTyler Gunn         * Starts the SIP service associated with the SIP profile.
49baee2955f596f7b79971feb12fa21031a069677dTyler Gunn         *
50baee2955f596f7b79971feb12fa21031a069677dTyler Gunn         * @param sipManager The SIP manager.
51baee2955f596f7b79971feb12fa21031a069677dTyler Gunn         * @param context The context.
52baee2955f596f7b79971feb12fa21031a069677dTyler Gunn         * @param isReceivingCalls {@code True} if the sip service is being started to make and
53baee2955f596f7b79971feb12fa21031a069677dTyler Gunn         *          receive calls.  {@code False} if the sip service is being started only for
54baee2955f596f7b79971feb12fa21031a069677dTyler Gunn         *          outgoing calls.
55baee2955f596f7b79971feb12fa21031a069677dTyler Gunn         * @return {@code True} if the service started successfully.
56baee2955f596f7b79971feb12fa21031a069677dTyler Gunn         */
57baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        boolean startSipService(SipManager sipManager, Context context, boolean isReceivingCalls) {
58baee2955f596f7b79971feb12fa21031a069677dTyler Gunn            if (VERBOSE) log("startSipService, profile: " + mProfile);
596556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon            try {
60baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                // Stop the Sip service for the profile if it is already running.  This is important
61baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                // if we are changing the state of the "receive calls" option.
62baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                sipManager.close(mProfile.getUriString());
63baee2955f596f7b79971feb12fa21031a069677dTyler Gunn
64baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                // Start the sip service for the profile.
65baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                if (isReceivingCalls) {
66baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                    sipManager.open(
67baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                            mProfile,
68baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                            SipUtil.createIncomingCallPendingIntent(context,
69f1b726aca6d599c93843fe1339b140a1690e683bBrad Ebinger                                    mProfile.getProfileName()),
70baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                            null);
71baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                } else {
72baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                    sipManager.open(mProfile);
73baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                }
746556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon                return true;
756556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon            } catch (SipException e) {
76baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                log("startSipService, profile: " + mProfile.getProfileName() +
776556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon                        ", exception: " + e);
786556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon            }
796556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon            return false;
806556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon        }
816556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
82baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        /**
83baee2955f596f7b79971feb12fa21031a069677dTyler Gunn         * Stops the SIP service associated with the SIP profile.  The {@code SipAccountRegistry} is
84baee2955f596f7b79971feb12fa21031a069677dTyler Gunn         * informed when the service has been stopped via an intent which triggers
85baee2955f596f7b79971feb12fa21031a069677dTyler Gunn         * {@link SipAccountRegistry#removeSipProfile(String)}.
86baee2955f596f7b79971feb12fa21031a069677dTyler Gunn         *
87baee2955f596f7b79971feb12fa21031a069677dTyler Gunn         * @param sipManager The SIP manager.
88baee2955f596f7b79971feb12fa21031a069677dTyler Gunn         * @return {@code True} if stop was successful.
89baee2955f596f7b79971feb12fa21031a069677dTyler Gunn         */
90baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        boolean stopSipService(SipManager sipManager) {
91baee2955f596f7b79971feb12fa21031a069677dTyler Gunn            try {
92baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                sipManager.close(mProfile.getUriString());
93baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                return true;
94baee2955f596f7b79971feb12fa21031a069677dTyler Gunn            } catch (Exception e) {
95baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                log("stopSipService, stop failed for profile: " + mProfile.getUriString() +
96baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                        ", exception: " + e);
974ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn            }
98baee2955f596f7b79971feb12fa21031a069677dTyler Gunn            return false;
996556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon        }
1006556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    }
1016556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
1026556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    private static final String PREFIX = "[SipAccountRegistry] ";
1036556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    private static final boolean VERBOSE = false; /* STOP SHIP if true */
1046556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    private static final SipAccountRegistry INSTANCE = new SipAccountRegistry();
1056556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
1066556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    private final List<AccountEntry> mAccounts = new CopyOnWriteArrayList<>();
1076556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
1086556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    private SipAccountRegistry() {}
1096556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
1104d37f5279f2896d16ec3d4e10ec4dcba63e86c3cAndrew Lee    public static SipAccountRegistry getInstance() {
1116556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon        return INSTANCE;
1126556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    }
1136556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
1146556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    void setup(Context context) {
115f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius        verifyAndPurgeInvalidPhoneAccounts(context);
1163a9e143aaa2c0ccae203641cf66cdc890383be01Santos Cordon        startSipProfilesAsync(context, (String) null, false);
117f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius    }
118e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon
119f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius    /**
120f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius     * Checks the existing SIP phone {@link PhoneAccount}s registered with telecom and deletes any
121f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius     * invalid accounts.
122f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius     *
123f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius     * @param context The context.
124f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius     */
125f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius    void verifyAndPurgeInvalidPhoneAccounts(Context context) {
126f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius        TelecomManager telecomManager = TelecomManager.from(context);
127f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius        SipProfileDb profileDb = new SipProfileDb(context);
128f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius        List<PhoneAccountHandle> accountHandles = telecomManager.getPhoneAccountsSupportingScheme(
129f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius                PhoneAccount.SCHEME_SIP);
130f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius
131f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius        for (PhoneAccountHandle accountHandle : accountHandles) {
132f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius            String profileName = SipUtil.getSipProfileNameFromPhoneAccount(accountHandle);
133f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius            SipProfile profile = profileDb.retrieveSipProfileFromName(profileName);
134f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius            if (profile == null) {
135f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius                log("verifyAndPurgeInvalidPhoneAccounts, deleting account: " + accountHandle);
136f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius                telecomManager.unregisterPhoneAccount(accountHandle);
137f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius            }
138f5992d586d7e25fafe5f271388a179e24ade75d8Roshan Pius        }
1396556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    }
1406556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
141baee2955f596f7b79971feb12fa21031a069677dTyler Gunn    /**
142baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * Starts the SIP service for the specified SIP profile and ensures it has a valid registered
143baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * {@link PhoneAccount}.
144baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     *
145baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * @param context The context.
146e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon     * @param sipProfileName The name of the {@link SipProfile} to start, or {@code null} for all.
1473a9e143aaa2c0ccae203641cf66cdc890383be01Santos Cordon     * @param enableProfile Sip account should be enabled
148baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     */
1493a9e143aaa2c0ccae203641cf66cdc890383be01Santos Cordon    void startSipService(Context context, String sipProfileName, boolean enableProfile) {
1503a9e143aaa2c0ccae203641cf66cdc890383be01Santos Cordon        startSipProfilesAsync(context, sipProfileName, enableProfile);
1516556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    }
1526556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
153baee2955f596f7b79971feb12fa21031a069677dTyler Gunn    /**
154baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * Removes a {@link SipProfile} from the account registry.  Does not stop/close the associated
155baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * SIP service (this method is invoked via an intent from the SipService once a profile has
156baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * been stopped/closed).
157baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     *
158e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon     * @param sipProfileName Name of the SIP profile.
159baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     */
160e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon    void removeSipProfile(String sipProfileName) {
161e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon        AccountEntry accountEntry = getAccountEntry(sipProfileName);
162baee2955f596f7b79971feb12fa21031a069677dTyler Gunn
163baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        if (accountEntry != null) {
164baee2955f596f7b79971feb12fa21031a069677dTyler Gunn            mAccounts.remove(accountEntry);
1656556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon        }
1666556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    }
1676556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
1686556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    /**
1694d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunn     * Stops a SIP profile and un-registers its associated {@link android.telecom.PhoneAccount}.
170baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * Called after a SIP profile is deleted.  The {@link AccountEntry} will be removed when the
171baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * service has been stopped.  The {@code SipService} fires the {@code ACTION_SIP_REMOVE_PHONE}
172baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * intent, which triggers {@link SipAccountRegistry#removeSipProfile(String)} to perform the
173baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * removal.
1746556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon     *
1756556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon     * @param context The context.
176e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon     * @param sipProfileName Name of the SIP profile.
1776556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon     */
178e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon    void stopSipService(Context context, String sipProfileName) {
179baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        // Stop the sip service for the profile.
180e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon        AccountEntry accountEntry = getAccountEntry(sipProfileName);
181baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        if (accountEntry != null ) {
182baee2955f596f7b79971feb12fa21031a069677dTyler Gunn            SipManager sipManager = SipManager.newInstance(context);
183baee2955f596f7b79971feb12fa21031a069677dTyler Gunn            accountEntry.stopSipService(sipManager);
184baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        }
185baee2955f596f7b79971feb12fa21031a069677dTyler Gunn
186baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        // Un-register its PhoneAccount.
187e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon        PhoneAccountHandle handle = SipUtil.createAccountHandle(context, sipProfileName);
1884d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunn        TelecomManager.from(context).unregisterPhoneAccount(handle);
189baee2955f596f7b79971feb12fa21031a069677dTyler Gunn    }
190baee2955f596f7b79971feb12fa21031a069677dTyler Gunn
191baee2955f596f7b79971feb12fa21031a069677dTyler Gunn    /**
192baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * Causes the SIP service to be restarted for all {@link SipProfile}s.  For example, if the user
193baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * toggles the "receive calls" option for SIP, this method handles restarting the SIP services
194baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * in the new mode.
195baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     *
196baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * @param context The context.
197baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     */
1984d37f5279f2896d16ec3d4e10ec4dcba63e86c3cAndrew Lee    public void restartSipService(Context context) {
1993a9e143aaa2c0ccae203641cf66cdc890383be01Santos Cordon        startSipProfiles(context, null, false);
200baee2955f596f7b79971feb12fa21031a069677dTyler Gunn    }
201baee2955f596f7b79971feb12fa21031a069677dTyler Gunn
202baee2955f596f7b79971feb12fa21031a069677dTyler Gunn    /**
203baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * Performs an asynchronous call to
204baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * {@link SipAccountRegistry#startSipProfiles(android.content.Context, String)}, starting the
2054d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunn     * specified SIP profile and registering its {@link android.telecom.PhoneAccount}.
206baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     *
207baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * @param context The context.
208e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon     * @param sipProfileName Name of the SIP profile.
2093a9e143aaa2c0ccae203641cf66cdc890383be01Santos Cordon     * @param enableProfile Sip account should be enabled.
210baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     */
2113a9e143aaa2c0ccae203641cf66cdc890383be01Santos Cordon    private void startSipProfilesAsync(
2123a9e143aaa2c0ccae203641cf66cdc890383be01Santos Cordon            final Context context, final String sipProfileName, final boolean enableProfile) {
213baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        if (VERBOSE) log("startSipProfiles, start auto registration");
214baee2955f596f7b79971feb12fa21031a069677dTyler Gunn
2156556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon        new Thread(new Runnable() {
2166556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon            @Override
2176556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon            public void run() {
2183a9e143aaa2c0ccae203641cf66cdc890383be01Santos Cordon                startSipProfiles(context, sipProfileName, enableProfile);
2196556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon            }}
2206556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon        ).start();
2216556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    }
2226556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
223baee2955f596f7b79971feb12fa21031a069677dTyler Gunn    /**
224baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * Loops through all SIP accounts from the SIP database, starts each service and registers
225e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon     * each with the telecom framework. If a specific sipProfileName is specified, this will only
226e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon     * register the associated SIP account.
227baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     *
228baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * @param context The context.
229e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon     * @param sipProfileName A specific SIP profile Name to start, or {@code null} to start all.
2303a9e143aaa2c0ccae203641cf66cdc890383be01Santos Cordon     * @param enableProfile Sip account should be enabled.
231baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     */
2323a9e143aaa2c0ccae203641cf66cdc890383be01Santos Cordon    private void startSipProfiles(Context context, String sipProfileName, boolean enableProfile) {
233b64b0a8e1f203b7628b6eeca9d0186803beaff7bBrad Ebinger        final SipPreferences sipPreferences = new SipPreferences(context);
234b64b0a8e1f203b7628b6eeca9d0186803beaff7bBrad Ebinger        boolean isReceivingCalls = sipPreferences.isReceivingCallsEnabled();
2354d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunn        TelecomManager telecomManager = TelecomManager.from(context);
236baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        SipManager sipManager = SipManager.newInstance(context);
237baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        SipProfileDb profileDb = new SipProfileDb(context);
238baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        List<SipProfile> sipProfileList = profileDb.retrieveSipProfileList();
2394ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn
240baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        for (SipProfile profile : sipProfileList) {
241baee2955f596f7b79971feb12fa21031a069677dTyler Gunn            // Register a PhoneAccount for the profile and optionally enable the primary
242baee2955f596f7b79971feb12fa21031a069677dTyler Gunn            // profile.
243e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon            if (sipProfileName == null || sipProfileName.equals(profile.getProfileName())) {
244baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                PhoneAccount phoneAccount = SipUtil.createPhoneAccount(context, profile);
2454d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunn                telecomManager.registerPhoneAccount(phoneAccount);
2463a9e143aaa2c0ccae203641cf66cdc890383be01Santos Cordon                if (enableProfile) {
2473a9e143aaa2c0ccae203641cf66cdc890383be01Santos Cordon                    telecomManager.enablePhoneAccount(phoneAccount.getAccountHandle(), true);
2483a9e143aaa2c0ccae203641cf66cdc890383be01Santos Cordon                }
24990f2ffdd00b47e2cd863d4361204c1a6fb31e3a0Nancy Chen                startSipServiceForProfile(profile, sipManager, context, isReceivingCalls);
2506556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon            }
2516556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon        }
2526556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    }
2536556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon
2544ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn    /**
255baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * Starts the SIP service for a sip profile and saves a new {@code AccountEntry} in the
256baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * registry.
257baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     *
258baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * @param profile The {@link SipProfile} to start.
259baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * @param sipManager The SIP manager.
2604ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn     * @param context The context.
261baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * @param isReceivingCalls {@code True} if the profile should be started such that it can
262baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     *      receive incoming calls.
2634ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn     */
264baee2955f596f7b79971feb12fa21031a069677dTyler Gunn    private void startSipServiceForProfile(SipProfile profile, SipManager sipManager,
265baee2955f596f7b79971feb12fa21031a069677dTyler Gunn            Context context, boolean isReceivingCalls) {
266baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        removeSipProfile(profile.getUriString());
267baee2955f596f7b79971feb12fa21031a069677dTyler Gunn
268baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        AccountEntry entry = new AccountEntry(profile);
269baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        if (entry.startSipService(sipManager, context, isReceivingCalls)) {
270baee2955f596f7b79971feb12fa21031a069677dTyler Gunn            mAccounts.add(entry);
271baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        }
272baee2955f596f7b79971feb12fa21031a069677dTyler Gunn    }
273baee2955f596f7b79971feb12fa21031a069677dTyler Gunn
274baee2955f596f7b79971feb12fa21031a069677dTyler Gunn    /**
275e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon     * Retrieves the {@link AccountEntry} from the registry with the specified name.
276baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     *
277e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon     * @param sipProfileName Name of the SIP profile to retrieve.
278baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     * @return The {@link AccountEntry}, or {@code null} is it was not found.
279baee2955f596f7b79971feb12fa21031a069677dTyler Gunn     */
280e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon    private AccountEntry getAccountEntry(String sipProfileName) {
281baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        for (AccountEntry entry : mAccounts) {
282e50b1903f2e84de2d23c035f8444cb83e1ae6226Santos Cordon            if (Objects.equals(sipProfileName, entry.getProfile().getProfileName())) {
283baee2955f596f7b79971feb12fa21031a069677dTyler Gunn                return entry;
284baee2955f596f7b79971feb12fa21031a069677dTyler Gunn            }
285baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        }
286baee2955f596f7b79971feb12fa21031a069677dTyler Gunn        return null;
2874ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn    }
2884ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn
2896556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    private void log(String message) {
2906556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon        Log.d(SipUtil.LOG_TAG, PREFIX + message);
2916556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    }
2926556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon}
293