10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (c) 2011 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony.cdma;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.concurrent.atomic.AtomicInteger;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CommandsInterface;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Registrant;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.RegistrantList;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.provider.Settings;
2999c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Class that handles the CDMA subscription source changed events from RIL
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class CdmaSubscriptionSourceManager extends Handler {
35cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String LOG_TAG = "CdmaSSM";
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 1;
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_GET_CDMA_SUBSCRIPTION_SOURCE     = 2;
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int EVENT_RADIO_ON                         = 3;
39a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final int EVENT_SUBSCRIPTION_STATUS_CHANGED      = 4;
40a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
41a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    // To know subscription is activated
42a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final int SUBSCRIPTION_ACTIVATED                 = 1;
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static final int SUBSCRIPTION_SOURCE_UNKNOWN = -1;
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static final int SUBSCRIPTION_FROM_RUIM      = 0; /* CDMA subscription from RUIM */
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static final int SUBSCRIPTION_FROM_NV        = 1; /* CDMA subscription from NV */
47867e0150ea9181755c681013f18877e8eab8ffffAmit Mahajan    public static final int PREFERRED_CDMA_SUBSCRIPTION = SUBSCRIPTION_FROM_RUIM;
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static CdmaSubscriptionSourceManager sInstance;
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final Object sReferenceCountMonitor = new Object();
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static int sReferenceCount = 0;
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // ***** Instance Variables
5422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private CommandsInterface mCi;
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private RegistrantList mCdmaSubscriptionSourceChangedRegistrants = new RegistrantList();
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Type of CDMA subscription source
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private AtomicInteger mCdmaSubscriptionSource = new AtomicInteger(SUBSCRIPTION_FROM_NV);
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Constructor
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private CdmaSubscriptionSourceManager(Context context, CommandsInterface ci) {
6222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi = ci;
6322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForCdmaSubscriptionChanged(this, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
6422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForOn(this, EVENT_RADIO_ON, null);
655ceae6074e0729fbbc422db2f263bf7cf453bf1aNaveen Kalla        int subscriptionSource = getDefault(context);
667e3260e3a9469b8d5b90665a7f9ccb359f8e708aJunda Liu        log("cdmaSSM constructor: " + subscriptionSource);
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCdmaSubscriptionSource.set(subscriptionSource);
68a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mCi.registerForSubscriptionStatusChanged(this, EVENT_SUBSCRIPTION_STATUS_CHANGED, null);
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * This function creates a single instance of this class
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return object of type CdmaSubscriptionSourceManager
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static CdmaSubscriptionSourceManager getInstance(Context context,
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CommandsInterface ci, Handler h, int what, Object obj) {
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (sReferenceCountMonitor) {
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (null == sInstance) {
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                sInstance = new CdmaSubscriptionSourceManager(context, ci);
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
82cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            CdmaSubscriptionSourceManager.sReferenceCount++;
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sInstance.registerForCdmaSubscriptionSourceChanged(h, what, obj);
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return sInstance;
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Unregisters for the registered event with RIL
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dispose(Handler h) {
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCdmaSubscriptionSourceChangedRegistrants.remove(h);
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (sReferenceCountMonitor) {
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            sReferenceCount--;
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (sReferenceCount <= 0) {
9622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.unregisterForCdmaSubscriptionChanged(this);
9722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.unregisterForOn(this);
98a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mCi.unregisterForSubscriptionStatusChanged(this);
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                sInstance = null;
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * (non-Javadoc)
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @see android.os.Handler#handleMessage(android.os.Message)
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void handleMessage(Message msg) {
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AsyncResult ar;
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_CDMA_SUBSCRIPTION_SOURCE:
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            {
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("CDMA_SUBSCRIPTION_SOURCE event = " + msg.what);
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handleGetCdmaSubscriptionSource(ar);
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_ON: {
12122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.getCdmaSubscriptionSource(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_SOURCE));
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
124a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case EVENT_SUBSCRIPTION_STATUS_CHANGED: {
125a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("EVENT_SUBSCRIPTION_STATUS_CHANGED");
126a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ar = (AsyncResult)msg.obj;
127a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (ar.exception == null) {
128a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    int actStatus = ((int[])ar.result)[0];
129a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    log("actStatus = " + actStatus);
130a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if (actStatus == SUBSCRIPTION_ACTIVATED) { // Subscription Activated
131a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        // In case of multi-SIM, framework should wait for the subscription ready
132a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        // to send any request to RIL.  Otherwise it will return failure.
133a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        Rlog.v(LOG_TAG,"get Cdma Subscription Source");
134a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        mCi.getCdmaSubscriptionSource(
135a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                                obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_SOURCE));
136a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
137a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                } else {
138a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    logw("EVENT_SUBSCRIPTION_STATUS_CHANGED, Exception:" + ar.exception);
139a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
140a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
141a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            break;
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                super.handleMessage(msg);
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Returns the current CDMA subscription source value
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return CDMA subscription source value
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public int getCdmaSubscriptionSource() {
1527e3260e3a9469b8d5b90665a7f9ccb359f8e708aJunda Liu        log("getcdmasubscriptionSource: " + mCdmaSubscriptionSource.get());
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return mCdmaSubscriptionSource.get();
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Gets the default CDMA subscription source
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return Default CDMA subscription source from Settings DB if present.
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1615ceae6074e0729fbbc422db2f263bf7cf453bf1aNaveen Kalla    public static int getDefault(Context context) {
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Get the default value from the Settings
1635ceae6074e0729fbbc422db2f263bf7cf453bf1aNaveen Kalla        int subscriptionSource = Settings.Global.getInt(context.getContentResolver(),
164b8d0e5993929ca9ecd29f406ae5f39a3e450e89bJeff Brown                Settings.Global.CDMA_SUBSCRIPTION_MODE, PREFERRED_CDMA_SUBSCRIPTION);
1657e3260e3a9469b8d5b90665a7f9ccb359f8e708aJunda Liu        Rlog.d(LOG_TAG, "subscriptionSource from settings: " + subscriptionSource);
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return subscriptionSource;
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Clients automatically register for CDMA subscription source changed event
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * when they get an instance of this object.
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void registerForCdmaSubscriptionSourceChanged(Handler h, int what, Object obj) {
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant (h, what, obj);
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCdmaSubscriptionSourceChangedRegistrants.add(r);
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Handles the call to get the subscription source
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param ar AsyncResult object that contains the result of get CDMA
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *            subscription source call
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handleGetCdmaSubscriptionSource(AsyncResult ar) {
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if ((ar.exception == null) && (ar.result != null)) {
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int newSubscriptionSource = ((int[]) ar.result)[0];
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (newSubscriptionSource != mCdmaSubscriptionSource.get()) {
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("Subscription Source Changed : " + mCdmaSubscriptionSource + " >> "
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        + newSubscriptionSource);
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mCdmaSubscriptionSource.set(newSubscriptionSource);
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Notify registrants of the new CDMA subscription source
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mCdmaSubscriptionSourceChangedRegistrants.notifyRegistrants(new AsyncResult(null,
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        null, null));
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
19858dd6858dc8013b680ea003d22063fd65ed5fe1cAmit Mahajan            // GET_CDMA_SUBSCRIPTION is returning Failure. Probably because modem created GSM Phone.
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            logw("Unable to get CDMA Subscription Source, Exception: " + ar.exception
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    + ", result: " + ar.result);
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void log(String s) {
205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Rlog.d(LOG_TAG, s);
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void logw(String s) {
209cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        Rlog.w(LOG_TAG, s);
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
213