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