CdmaSubscriptionSourceManager.java revision cbaa45bbf2cab852b6c9c3a887e9f803d4e857ea
1/*
2 * Copyright (c) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.telephony.cdma;
18
19import java.util.concurrent.atomic.AtomicInteger;
20
21import com.android.internal.telephony.CommandsInterface;
22import android.content.Context;
23import android.os.AsyncResult;
24import android.os.Handler;
25import android.os.Message;
26import android.os.Registrant;
27import android.os.RegistrantList;
28import android.provider.Settings;
29import android.telephony.Rlog;
30
31/**
32 * Class that handles the CDMA subscription source changed events from RIL
33 */
34public class CdmaSubscriptionSourceManager extends Handler {
35    static final String LOG_TAG = "CdmaSSM";
36    private static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 1;
37    private static final int EVENT_GET_CDMA_SUBSCRIPTION_SOURCE     = 2;
38    private static final int EVENT_RADIO_ON                         = 3;
39
40    public static final int SUBSCRIPTION_SOURCE_UNKNOWN = -1;
41    public static final int SUBSCRIPTION_FROM_RUIM      = 0; /* CDMA subscription from RUIM */
42    public static final int SUBSCRIPTION_FROM_NV        = 1; /* CDMA subscription from NV */
43    public static final int PREFERRED_CDMA_SUBSCRIPTION = SUBSCRIPTION_FROM_NV;
44
45    private static CdmaSubscriptionSourceManager sInstance;
46    private static final Object sReferenceCountMonitor = new Object();
47    private static int sReferenceCount = 0;
48
49    // ***** Instance Variables
50    private CommandsInterface mCM;
51    private Context mContext;
52    private RegistrantList mCdmaSubscriptionSourceChangedRegistrants = new RegistrantList();
53
54    // Type of CDMA subscription source
55    private AtomicInteger mCdmaSubscriptionSource = new AtomicInteger(SUBSCRIPTION_FROM_NV);
56
57    // Constructor
58    private CdmaSubscriptionSourceManager(Context context, CommandsInterface ci) {
59        mContext = context;
60        mCM = ci;
61        mCM.registerForCdmaSubscriptionChanged(this, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
62        mCM.registerForOn(this, EVENT_RADIO_ON, null);
63        int subscriptionSource = getDefaultCdmaSubscriptionSource();
64        mCdmaSubscriptionSource.set(subscriptionSource);
65    }
66
67    /**
68     * This function creates a single instance of this class
69     *
70     * @return object of type CdmaSubscriptionSourceManager
71     */
72    public static CdmaSubscriptionSourceManager getInstance(Context context,
73            CommandsInterface ci, Handler h, int what, Object obj) {
74        synchronized (sReferenceCountMonitor) {
75            if (null == sInstance) {
76                sInstance = new CdmaSubscriptionSourceManager(context, ci);
77            }
78            CdmaSubscriptionSourceManager.sReferenceCount++;
79        }
80        sInstance.registerForCdmaSubscriptionSourceChanged(h, what, obj);
81        return sInstance;
82    }
83
84    /**
85     * Unregisters for the registered event with RIL
86     */
87    public void dispose(Handler h) {
88        mCdmaSubscriptionSourceChangedRegistrants.remove(h);
89        synchronized (sReferenceCountMonitor) {
90            sReferenceCount--;
91            if (sReferenceCount <= 0) {
92                mCM.unregisterForCdmaSubscriptionChanged(this);
93                mCM.unregisterForOn(this);
94                sInstance = null;
95            }
96        }
97    }
98
99    /*
100     * (non-Javadoc)
101     * @see android.os.Handler#handleMessage(android.os.Message)
102     */
103    @Override
104    public void handleMessage(Message msg) {
105        AsyncResult ar;
106        switch (msg.what) {
107            case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
108            case EVENT_GET_CDMA_SUBSCRIPTION_SOURCE:
109            {
110                log("CDMA_SUBSCRIPTION_SOURCE event = " + msg.what);
111                ar = (AsyncResult) msg.obj;
112                handleGetCdmaSubscriptionSource(ar);
113            }
114            break;
115            case EVENT_RADIO_ON: {
116                mCM.getCdmaSubscriptionSource(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_SOURCE));
117            }
118            break;
119            default:
120                super.handleMessage(msg);
121        }
122    }
123
124    /**
125     * Returns the current CDMA subscription source value
126     * @return CDMA subscription source value
127     */
128    public int getCdmaSubscriptionSource() {
129        return mCdmaSubscriptionSource.get();
130    }
131
132    /**
133     * Gets the default CDMA subscription source
134     *
135     * @return Default CDMA subscription source from Settings DB if present.
136     */
137    private int getDefaultCdmaSubscriptionSource() {
138        // Get the default value from the Settings
139        int subscriptionSource = Settings.Global.getInt(mContext.getContentResolver(),
140                Settings.Global.CDMA_SUBSCRIPTION_MODE, PREFERRED_CDMA_SUBSCRIPTION);
141        return subscriptionSource;
142    }
143
144    /**
145     * Clients automatically register for CDMA subscription source changed event
146     * when they get an instance of this object.
147     */
148    private void registerForCdmaSubscriptionSourceChanged(Handler h, int what, Object obj) {
149        Registrant r = new Registrant (h, what, obj);
150        mCdmaSubscriptionSourceChangedRegistrants.add(r);
151    }
152
153    /**
154     * Handles the call to get the subscription source
155     *
156     * @param ar AsyncResult object that contains the result of get CDMA
157     *            subscription source call
158     */
159    private void handleGetCdmaSubscriptionSource(AsyncResult ar) {
160        if ((ar.exception == null) && (ar.result != null)) {
161            int newSubscriptionSource = ((int[]) ar.result)[0];
162
163            if (newSubscriptionSource != mCdmaSubscriptionSource.get()) {
164                log("Subscription Source Changed : " + mCdmaSubscriptionSource + " >> "
165                        + newSubscriptionSource);
166                mCdmaSubscriptionSource.set(newSubscriptionSource);
167
168                // Notify registrants of the new CDMA subscription source
169                mCdmaSubscriptionSourceChangedRegistrants.notifyRegistrants(new AsyncResult(null,
170                        null, null));
171            }
172        } else {
173            // GET_CDMA_SUBSCRIPTION is returning Failure. Probably
174            // because modem created GSM Phone. If modem created
175            // GSMPhone, then PhoneProxy will trigger a change in
176            // Phone objects and this object will be destroyed.
177            logw("Unable to get CDMA Subscription Source, Exception: " + ar.exception
178                    + ", result: " + ar.result);
179        }
180    }
181
182    private void log(String s) {
183        Rlog.d(LOG_TAG, s);
184    }
185
186    private void logw(String s) {
187        Rlog.w(LOG_TAG, s);
188    }
189
190}
191