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 android.content.Context; 23 import android.os.AsyncResult; 24 import android.os.Handler; 25 import android.os.Message; 26 import android.os.Registrant; 27 import android.os.RegistrantList; 28 import android.provider.Settings; 29 import android.telephony.Rlog; 30 31 /** 32 * Class that handles the CDMA subscription source changed events from RIL 33 */ 34 public 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 mCi; 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 mCi = ci; 61 mCi.registerForCdmaSubscriptionChanged(this, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null); 62 mCi.registerForOn(this, EVENT_RADIO_ON, null); 63 int subscriptionSource = getDefault(context); 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 mCi.unregisterForCdmaSubscriptionChanged(this); 93 mCi.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 mCi.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 public static int getDefault(Context context) { 138 // Get the default value from the Settings 139 int subscriptionSource = Settings.Global.getInt(context.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